<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<title>sento documentation
</title>
<link type='text/css' href='style.css' rel='stylesheet'>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
   <script src="jquery.min.js"></script>
<script src="toc.min.js"></script>
<script type="text/x-mathjax-config">
     MathJax.Hub.Config({
       tex2jax: {
         inlineMath: [['$','$']],
         processEscapes: true
       }
     });
   </script>
   <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML">
   </script>
   
</head>
<body>
<div id="content-container">
<div id="toc">
<div id="page-toc">
</div>
<div id="toc-footer"><ul><li><a href="https://github.com/melisgl/mgl-pax">[generated by MGL-PAX]</a></li></ul></div>
</div>
<div id="content">
<p><a id="x-28SENTO-2EDOCS-3A-40SENTO-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.DOCS:@SENTO%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.DOCS:@README%20MGL-PAX:SECTION" title="Introduction">&#8594;</a> <a href="sento.html" title="sento documentation">&#8634;</a></span></span></p>
<h1><a href="sento.html">sento documentation</a></h1>
<h2>Table of Contents</h2>
<ul>
<li><a href="#SENTO.DOCS:@README%20MGL-PAX:SECTION" title="Introduction">1 Introduction</a></li>
<li><a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">2 API documentation</a>

<ul>
<li><a href="#SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION" title="Actor-System">2.1 Actor-System</a></li>
<li><a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION" title="Actor-Context">2.2 Actor-Context</a>

<ul>
<li><a href="#SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION" title="Actor-Context protocol">2.2.1 Actor-Context protocol</a></li>
</ul></li>
<li><a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">2.3 Actor</a>

<ul>
<li><a href="#SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION" title="Actor-Cell">2.3.1 Actor-Cell</a></li>
<li><a href="#SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION" title="Message-box base class">2.3.2 Message-box base class</a></li>
<li><a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION" title="Message-box threaded">2.3.3 Message-box threaded</a></li>
<li><a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION" title="Message-box dispatched">2.3.4 Message-box dispatched</a></li>
</ul></li>
<li><a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">2.4 Agent</a>

<ul>
<li><a href="#SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION" title="Hash-table agent">2.4.1 Hash-table agent</a></li>
<li><a href="#SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION" title="Array/Vector agent">2.4.2 Array/Vector agent</a></li>
</ul></li>
<li><a href="#SENTO.FSM:@FSM%20MGL-PAX:SECTION" title="Finite state machine">2.5 Finite state machine</a></li>
<li><a href="#SENTO.STASH:@STASHING%20MGL-PAX:SECTION" title="Stashing">2.6 Stashing</a></li>
<li><a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION" title="Dispatcher">2.7 Dispatcher</a>

<ul>
<li><a href="#SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION" title="Shared dispatcher">2.7.1 Shared dispatcher</a></li>
</ul></li>
<li><a href="#SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION" title="Router">2.8 Router</a></li>
<li><a href="#SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION" title="Eventstream">2.9 Eventstream</a></li>
<li><a href="#SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION" title="Future (delayed-computation)">2.10 Future (delayed-computation)</a></li>
<li><a href="#SENTO.TASKS:@TASKS%20MGL-PAX:SECTION" title="Tasks">2.11 Tasks</a></li>
<li><a href="#SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION" title="Config">2.12 Config</a></li>
<li><a href="#SENTO.WHEEL-TIMER:@SCHEDULER%20MGL-PAX:SECTION" title="Scheduler">2.13 Scheduler</a></li>
</ul></li>
</ul>
<h6>[in package SENTO.DOCS]</h6>
<p><a id="x-28SENTO-2EDOCS-3A-40README-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.DOCS:@README%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="sento.html" title="sento documentation">&#8592;</a> <a href="sento.html" title="sento documentation">&#8593;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8594;</a> <a href="#SENTO.DOCS:@README%20MGL-PAX:SECTION" title="Introduction">&#8634;</a></span></span></p>
<h2><a href="#SENTO.DOCS:@README%20MGL-PAX:SECTION">1 Introduction</a></h2>
<p><img src="https://github.com/mdbergmann/cl-gserver/workflows/CI/badge.svg?branch=master" alt="CI" /></p>
<h3>Introduction - Actor framework featuring actors and agents</h3>
<p><strong>Sento</strong> is a 'message passing' library/framework with actors similar to Erlang or Akka. It supports creating systems that should work reactive, require parallel computing and event based message handling.</p>
<p>Sento features:</p>
<ul>
<li>Actors with <code>ask</code> (<code>?</code>) and <code>tell</code> (<code>!</code>) operations. <code>ask</code> can be asynchronous or synchronous.</li>
<li>Agents: Agents are a specialization of Actors for wrapping state with a standardized interface of <code>init</code>, <code>get</code> and <code>set</code>. There are also specialized Agents for Common Lisps array and hash-map data structures.</li>
<li>Router: Router offers a similar interface as Actor with <code>ask</code> and <code>tell</code> but collects multiple Actors for load-balancing.</li>
<li>EventStream: all Actors and Agents are connected to an EventStream and can subscribe to messages or publish messages. This is similar to an event-bus.</li>
<li>Tasks: a simple API for concurrency.</li>
</ul>
<p>(Please also checkout the API <a href="https://mdbergmann.github.io/cl-gserver/index.html" >documentation</a> for further information)
(for migrations from Sento v2, please check below migration guide)</p>
<h3>Projects using Sento (for example usage):</h3>
<ul>
<li><a href="https://github.com/mdbergmann/chipi" >Chipi automation tool</a>: Actors used for foundational primitives like 'items' and 'persistences'.</li>
<li><a href="https://github.com/mdbergmann/knx-conn" >KNX-conn</a>: Used for asynchronous reading/writing from/to KNX bus</li>
<li><a href="https://github.com/mdbergmann/cl-tbnl-gserver-tmgr" >Hunchentoot taskmanager</a>: High throughput Hunchentoot task manager</li>
</ul>
<h3>Intro</h3>
<h4>Creating an actor-system</h4>
<p>The first thing you wanna do is to create an actor system.
In simple terms, an actor system is a container where all actors live in. So at any time the actor system knows which actors exist.</p>
<p>To create an actor system we can first change package to <code>:sento-user</code> because it imports the majority of necessary namespaces fopr convenience. Then, do:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_143.html#IDX430" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*system*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span></span></code></pre>
<p>When we look at <code>*system*</code> in the repl we see some information of the actor system:</p>
<pre><code>#&lt;ACTOR-SYSTEM config: (DISPATCHERS
                        (SHARED (WORKERS 4 STRATEGY RANDOM))
                        TIMEOUT-TIMER
                        (RESOLUTION 500 MAX-SIZE 1000)
                        EVENTSTREAM
                        (DISPATCHER-ID SHARED)
                        SCHEDULER
                        (ENABLED TRUE RESOLUTION 100 MAX-SIZE 500)
                        ), user actors: 0, internal actors: 5&gt;</code></pre>
<p>The <code>actor-system</code> has, by default, four shared message dispatcher workers. Depending on how busy the system tends to be this default can be increased. Those four workers are part of the 'internal actors'. The 5th actor drives the event-stream (later more on that, but in a nutshell it's something like an event bus).</p>
<p>There are none 'user actors' yet, and the 'config' is the default config specifying the number of message dispatch workers (4) and the strategy they use to balance throughput, 'random' here.</p>
<p>Using a custom config is it possible to change much of those defaults. For instance, create custom dispatchers, i.e. a dedicated dispatcher used for the 'Tasks' api (see later for more info). The event-stream by default uses the global 'shared' dispatcher. Changing the config it would be possible to have the event-stream actor use a <code>:pinned</code> dispatcher (more on dispatchers later) to optimize throughput. Etc.</p>
<p>Actors live in the actor system, but more concrete in an <code>actor-context</code>. An <code>actor-context</code> contains a collection (of actors) and represents a Common Lisp protocol that defines a set of generic functions for creating, removing and finding actors in an <code>actor-context</code>. The actor system itself is also implementing the <code>actor-context</code> protocol, so it also acts as such and hence the protocol <code>ac</code> (<code>actor-context</code>) is used to operate on the actor system.</p>
<p>I.e. to shutdown the actor system one has to execute: <code>(ac:shutdown *system*)</code>.</p>
<h4>Creating and using actors</h4>
<p>Now we want to create actors.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">actor-of <span class="special">*system*</span> <span class="keyword">:name</span> <span class="string">"answerer"</span>
  <span class="keyword">:receive</span>
  <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
    <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">output <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"Hello ~a"</span> msg</span>)</span></span>)</span></span>)</span>
        <span class="paren4">(<span class="code">reply output</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This creates an actor in <code>*system*</code>. Notice that the actor is not assigned to a variable (but you can). It is now registered in the system. Using function <code>ac:find-actors</code> you'll be able to find it again. Of course it makes sense to store important actors that are frequently used in a <code>defparameter</code> variable.</p>
<p>The <code>:receive</code> key argument to <code>actor-of</code> is a function which implements the message processing behaviour of an actor. The parameter to the 'receive' function is just the received message (msg).</p>
<p><code>actor-of</code> also allows to specify the initial state, a name, and a custom actor type via key parameters. By default a standard actor of type <code>'actor</code> is created. It is possible to subclass <code>'actor</code> and specify your own. It is further possible to specify an 'after initialization' function, using the <code>:init</code> key, and 'after destroy' function using <code>:destroy</code> keyword. <code>:init</code> can, for example, be used to subscribe to the event-stream for listening to important messages.</p>
<p>The return value of 'receive' function is only used when using the synchronous <code>ask-s</code> function to 'ask' the actor. Using <code>ask</code> (equivalent: <code>?</code>) the return value is ignored. If an answer should be provided to an asking actor, or if replying is part of an interface contract, then <code>reply</code> should be used.</p>
<p>The above actor was stored to a variable <code>*answerer*</code>. We can evaluate this in repl and see:</p>
<pre><code><span class="code">#&lt;ACTOR path: /user/answerer, cell: #&lt;ACTOR answerer, running: T, state: NIL, message-box: #&lt;SENTO.MESSAGEB:MESSAGE-BOX/DP mesgb-1356, processed messages: 1, max-queue-size: 0, queue: #&lt;SENTO.QUEUE:QUEUE-UNBOUNDED 82701A6D13&gt;&gt;&gt;&gt;</span></code></pre>
<p>We'll see the 'path' of the actor. The prefix '/user' means that the actor was created in a user actor context of the actor system. Further we see whether the actor is 'running', its 'state' and the used 'message-box' type, by default it uses an unbounded queue.</p>
<p>Now, when sending a message using 'ask' pattern to the above actor like so:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">? <span class="special">*answerer*</span> <span class="string">"FooBar"</span></span>)</span></span></code></pre>
<p>we'll get a 'future' as result, because <code>?</code>/<code>ask</code> is asynchronous.</p>
<pre><code>#&lt;FUTURE promise: #&lt;BLACKBIRD-BASE:PROMISE
finished: NIL
errored: NIL
forward: NIL 80100E8B7B&gt;&gt;</code></pre>
<p>We can check for a 'future' result. By now the answer from the <code>*answerer*</code> (via <code>reply</code>) should be available:</p>
<pre><code>USER&gt; (fresult *)
"Hello FooBar"</code></pre>
<p>If the reply had not been received yet, <code>fresult</code> would return <code>:not-ready</code>. So, <code>fresult</code> doesn't block, it is necessary to repeatedly probe using <code>fresult</code> until result is other than <code>:not-ready</code>.</p>
<p>A nicer and asynchronous way without querying is to use <code>fcompleted</code>. Using <code>fcompleted</code> you setup a callback function that is called with the result when it is available. Like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">fcompleted
     <span class="paren2">(<span class="code">? <span class="special">*answerer*</span> <span class="string">"Buzz"</span></span>)</span>
     <span class="paren2">(<span class="code">result</span>)</span>
   <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"The answer is: ~a~%"</span> result</span>)</span></span>)</span></span></code></pre>
<p>Which will asynchronously print <em>&quot;The answer is: Hello Buzz&quot;</em> after a short while.
This will also work when the <code>ask</code>/<code>?</code> was used with a timeout, in which case <code>result</code> will be a tuple of <code>(:handler-error . &lt;ask-timeout condition&gt;)</code> if the operation timed out.</p>
<h4>Creating child actors</h4>
<p>To build actor hierarchies one has to create actors in actors. This is of course possible. There are two options for this.</p>
<ol>
<li>Actors are created as part of <code>actor-of</code>s <code>:init</code> function like so:</li>
</ol>
<pre><code><span class="code"><span class="paren1">(<span class="code">actor-of <span class="special">*system*</span> 
          <span class="keyword">:name</span> <span class="string">"answerer-with-child"</span>
          <span class="keyword">:receive</span>
          <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
            <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">output <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"Hello ~a"</span> msg</span>)</span></span>)</span></span>)</span>
              <span class="paren4">(<span class="code">reply output</span>)</span></span>)</span></span>)</span>
          <span class="keyword">:init</span>
          <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">self</span>)</span>
            <span class="paren3">(<span class="code">actor-of self 
                      <span class="keyword">:name</span> <span class="string">"child-answerer"</span>
                      <span class="keyword">:receive</span> 
                      <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="code">msg</span>)</span>
                        <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren6">(<span class="code"><span class="paren1">(<span class="code">output <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"Hello-child ~a"</span> msg</span>)</span></span>)</span></span>)</span>
                          <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"~a~%"</span> output</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Notice the context for creating 'child-answerer', it is <code>self</code>, which is 'answerer-with-child'.</p>
<ol>
<li>Or it is possible externally like so:</li>
</ol>
<pre><code><span class="code"><span class="paren1">(<span class="code">actor-of <span class="special">*answerer*</span> <span class="keyword">:name</span> <span class="string">"child-answerer"</span>
    <span class="keyword">:receive</span> 
    <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
        <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">output <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"~a"</span> <span class="string">"Hello-child ~a"</span> msg</span>)</span></span>)</span></span>)</span>
            <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"~a~%"</span> output</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This uses <code>*answerer*</code> context as parameter of <code>actor-of</code>. But has the same effect as above.</p>
<p>Now we can check if there is an actor in context of 'answerer-with-child':</p>
<pre><code>USER&gt; (all-actors *actor-with-child*)
(#&lt;ACTOR path: /user/answerer-with-child/child-answerer, cell: #&lt;ACTOR child-answerer, running: T, state: NIL, message-box: #&lt;SENTO.MESSAGEB:MESSAGE-BOX/DP mesgb-1374, processed messages: 0, max-queue-size: 0, queue: #&lt;SENTO.QUEUE:QUEUE-UNBOUNDED 8200A195FB&gt;&gt;&gt;&gt;)</code></pre>
<p>The 'path' is what we expected: '/user/answerer-with-child/child-answerer'.</p>
<h4>Ping Pong</h4>
<p>Another example that only works with <code>tell</code>/<code>!</code> (fire and forget).</p>
<p>We have those two actors.</p>
<p>The 'ping' actor:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*ping*</span>
  <span class="paren2">(<span class="code">actor-of <span class="special">*system*</span>
            <span class="keyword">:receive</span>
            <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code">msg</span>)</span>
              <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_126.html#IDX389" class="symbol"><i><span class="symbol">cond</span></i></a>
                <span class="paren5">(<span class="code"><span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_81.html#IDX199" class="symbol">consp</a> msg</span>)</span>
                 <span class="paren6">(<span class="code">case <span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_82.html#IDX205" class="symbol">car</a> msg</span>)</span>
                   <span class="paren1">(<span class="code"><span class="keyword">:start-ping</span>
                    <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_125.html#IDX383" class="symbol"><i><span class="symbol">progn</span></i></a>
                      <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"Starting ping...~%"</span></span>)</span>
                      <span class="paren3">(<span class="code">! <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_82.html#IDX206" class="symbol">cdr</a> msg</span>)</span> <span class="keyword">:ping</span> <span class="special">*self*</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
                <span class="paren5">(<span class="code"><span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_56.html#IDX68" class="symbol">eq</a> msg <span class="keyword">:pong</span></span>)</span>
                 <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_125.html#IDX383" class="symbol"><i><span class="symbol">progn</span></i></a>
                   <span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"pong~%"</span></span>)</span>
                   <span class="paren1">(<span class="code">sleep 2</span>)</span>
                   <span class="paren1">(<span class="code">reply <span class="keyword">:ping</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>And the 'pong' actor:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*pong*</span>
  <span class="paren2">(<span class="code">actor-of <span class="special">*system*</span>
            <span class="keyword">:receive</span>
            <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code">msg</span>)</span>
              <span class="paren4">(<span class="code">case msg
                <span class="paren5">(<span class="code"><span class="keyword">:ping</span>
                 <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_125.html#IDX383" class="symbol"><i><span class="symbol">progn</span></i></a>
                   <span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"ping~%"</span></span>)</span>
                   <span class="paren1">(<span class="code">sleep 2</span>)</span>
                   <span class="paren1">(<span class="code">reply <span class="keyword">:pong</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>The 'ping' actor understands a <code>:start-ping</code> message which is a <code>cons</code> and has as <code>cdr</code> the 'pong' actor instance.
It also understands a <code>:pong</code> message as received from 'pong' actor.</p>
<p>The 'pong' actor only understands a <code>:ping</code> message. Each of the actors respond with either <code>:ping</code> or <code>:pong</code> respectively after waiting 2 seconds.</p>
<p>We trigger the ping-pong by doing:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">! <span class="special">*ping*</span> `<span class="paren2">(<span class="code"><span class="keyword">:start-ping</span> . ,<span class="special">*pong*</span></span>)</span></span>)</span></span></code></pre>
<p>And then see in the console like:</p>
<pre><code>Starting ping...
ping
pong
ping
...</code></pre>
<p>To stop the ping-pong one just has to send <code>(! *ping* :stop)</code> to one of them.</p>
<p><code>:stop</code> will completely stop the actors message processing, and the actor will not be useable anymore.</p>
<h5>Synchronous ask</h5>
<p>At last an example for the synchronous 'ask', <code>ask-s</code>. It is insofar similar to <code>ask</code> that it provides a result to the caller. However, it is not bound to <code>reply</code> as with <code>ask</code>. Here, the return value of the 'receive' function is returned to the caller, and <code>ask-s</code> will block until 'receive' function returns.<br/>
Beware that <code>ask-s</code> will dead-lock your actor when <code>ask-s</code> is used to call itself.<br/>
Let's make an example:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*s-asker*</span>
  <span class="paren2">(<span class="code">actor-of <span class="special">*system*</span>
            <span class="keyword">:receive</span>
            <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code">msg</span>)</span>
              <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_126.html#IDX389" class="symbol"><i><span class="symbol">cond</span></i></a>
                <span class="paren5">(<span class="code"><span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_70.html#IDX146" class="symbol">stringp</a> msg</span>)</span>
                 <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"Hello ~a"</span> msg</span>)</span></span>)</span>
                <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a> <span class="string">"Unknown message!"</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>So we can do:</p>
<pre><code>USER&gt; (ask-s *s-asker* "Foo")
"Hello Foo"
USER&gt; (ask-s *s-asker* 'foo)
"Unknown message!"</code></pre>
<h4>Dispatchers <code>:pinned</code> vs. <code>:shared</code></h4>
<p>Dispatchers are somewhat alike thread pools. Dispatchers of the <code>:shared</code> type are a pool of workers. Workers are actors using a <code>:pinned</code> dispatcher. <code>:pinned</code> just means that an actor spawns its own mailbox thread.</p>
<p>So <code>:pinned</code> and <code>:shared</code> are types of dispatchers. <code>:pinned</code> spawns its own mailbox thread, <code>:shared</code> uses a worker pool to handle the mailbox messages.</p>
<p>By default an actor created using <code>actor-of</code> uses a <code>:shared</code> dispatcher type which uses the shared message dispatcher that is automatically setup in the system.</p>
<p>When creating an actor it is possible to specify the <code>dispatcher-id</code>. This parameter specifies which 'dispatcher' should handle the mailbox queue/messages.</p>
<p>Please see below for more info on dispatchers.</p>
<h4>Finding actors in the context</h4>
<p>If actors are not directly stored in a dynamic or lexical context they can still be looked up and used. The <code>actor-context</code> protocol contains a function <code>find-actors</code> which can lookup actors in various ways. Checkout the API <a href="https://mdbergmann.github.io/cl-gserver/index.html#SENTO.ACTOR-CONTEXT:FIND-ACTORS%20GENERIC-FUNCTION" >documentation</a>.</p>
<h4>Mapping futures with fmap</h4>
<p>Let's asume we have such a simple actor that just increments the value passed to it.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*incer*</span>
  <span class="paren2">(<span class="code">actor-of <span class="special">*system*</span>
            <span class="keyword">:receive</span> <span class="paren3">(<span class="code"><i><span class="symbol">lambda</span></i> <span class="paren4">(<span class="code">value</span>)</span>
                       <span class="paren4">(<span class="code">reply <span class="paren5">(<span class="code">1+ value</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Since <code>ask</code> returns a future it is possible to map multiple <code>ask</code> operations like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">-&gt; <span class="paren2">(<span class="code">ask <span class="special">*incer*</span> 0</span>)</span>
  <span class="paren2">(<span class="code">fmap <span class="paren3">(<span class="code">result</span>)</span>
      <span class="paren3">(<span class="code">ask <span class="special">*incer*</span> result</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">fmap <span class="paren3">(<span class="code">result</span>)</span>
      <span class="paren3">(<span class="code">ask <span class="special">*incer*</span> result</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">fcompleted <span class="paren3">(<span class="code">result</span>)</span>
      <span class="paren3">(<span class="code">format t <span class="string">"result: ~a~%"</span> result</span>)</span>
    <span class="paren3">(<span class="code">assert <span class="paren4">(<span class="code">= result 3</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<h4>ask-s and ask with timeout</h4>
<p>A timeout (in seconds) can be specified for both <code>ask-s</code> and
<code>ask</code> and is done like so:</p>
<p>To demonstrate this we could setup an example 'sleeper' actor:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">ac:actor-of <span class="special">*system*</span> 
    <span class="keyword">:receive</span> 
    <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
        <span class="paren3">(<span class="code">sleep 5</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>If we store this to <code>*sleeper*</code> and do the following, the
<code>ask-s</code> will return a <code>handler-error</code> with an
<code>ask-timeout</code> condition.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">act:ask-s <span class="special">*sleeper*</span> <span class="string">"Foo"</span> <span class="keyword">:time-out</span> 2</span>)</span></span></code></pre>
<pre><code><span class="code"><span class="paren1">(<span class="code"><span class="keyword">:HANDLER-ERROR</span> . #&lt;CL-GSERVER.UTILS:ASK-TIMEOUT #x30200319F97D&gt;</span>)</span></span></code></pre>
<p>This works similar with the <code>ask</code> only that the future will
be fulfilled with the <code>handler-error</code> <code>cons</code>.</p>
<p>To get a readable error message of the condition we can do:</p>
<pre><code><span class="code">CL-USER&gt; <span class="paren1">(<span class="code">format t <span class="string">"~a"</span> <span class="paren2">(<span class="code">cdr *</span>)</span></span>)</span>
A timeout set to 2 seconds occurred. Cause: 
#&lt;BORDEAUX-THREADS:TIMEOUT #x302002FAB73D&gt; </span></code></pre>
<p>Note that <code>ask-s</code> uses the calling thread for the timeout checks.<br/>
<code>ask</code> uses a wheel timer to handle timeouts. The default resolution for <code>ask</code> timeouts is 500ms with a maximum size of wheel slots (registered timeouts) of 1000. What this means is that you can have timeouts of a multiple of 500ms and 1000 <code>ask</code> operations with timeouts. This default can be tweaked when creating an actor-system, see API <a href="https://mdbergmann.github.io/cl-gserver/index.html#SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE" >documentation</a> for more details.</p>
<h4>Long running and asynchronous operations in <code>receive</code></h4>
<p>Be careful with doing long running computations in the <code>receive</code> function message handler, because it will block message processing. It is advised to use a third-party thread-pool or a library like <em>lparallel</em> to do the computations with, and return early from the <code>receive</code> message handler.</p>
<p>The computation result can be 'awaited' for in an asynchronous manner and a response to <code>*sender*</code> can be sent manually (via <code>reply</code>). The sender of the original message is set to the dynamic variable <code>*sender*</code>.</p>
<p>Due to an asynchronous callback of a computation running is a separate thread, the <code>*sender*</code> must be copied into a lexical environment because at the time of when the callback is executed the <code>*sender*</code> can have a different value.</p>
<p>For instance, if there is a potentially long running and asynchronous operation happening in 'receive', the <em>original</em> sender must be captured and the async operation executed in a lexical context, like so (receive function):</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren2">(<span class="code">msg</span>)</span>
  <span class="paren2">(<span class="code">case msg
    <span class="paren3">(<span class="code"><span class="keyword">:do-lengthy-op</span>
     <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren5">(<span class="code"><span class="paren6">(<span class="code">sender <span class="special">*sender*</span></span>)</span></span>)</span>
       <span class="comment">;; do lengthy computation
</span>       <span class="paren5">(<span class="code">reply <span class="keyword">:my-later-reply</span> sender</span>)</span></span>)</span></span>)</span>
    <span class="paren3">(<span class="code">otherwise
      <span class="comment">;; do other non async stuff
</span>      <span class="paren4">(<span class="code">reply <span class="keyword">:my-reply</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Notice that for the lengthy operation the sender must be captured because if the lengthy operation is asynchronous 'receive' function is perhaps called for another message where <code>*sender*</code> is different. In that case <code>sender</code> must be supplied explicitly for <code>reply</code>.</p>
<p>See <a href="../tests/spawn-in-receive-test.lisp" >this test</a> for more info.</p>
<p>NOTE: you should not change actor state from within an asynchronously executed operation in <code>receive</code>. This is not thread-safe. The pattern for this case it to send a message to <code>self</code> and have a message handler case that will change the actor state. This will ensure that actor state is always changed in a thread-safe way.</p>
<h4>Changing behavior</h4>
<p>An actor can change its behavior. The behavior is just a lambda similar as the 'receive' function taking the message as parameter.</p>
<p>The default behavior of the actor is given on actor construction using <code>:receive</code> key.</p>
<p>During the lifetime of an actor the behavior can be changed using <code>become</code>. <code>unbecome</code> will restore the default behavior.</p>
<p>Here is an example:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">ac:actor-of <span class="special">*system*</span>
             <span class="keyword">:receive</span>
             <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
               <span class="paren3">(<span class="code">case msg
                 <span class="paren4">(<span class="code"><span class="keyword">:open</span>
                  <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_125.html#IDX383" class="symbol"><i><span class="symbol">progn</span></i></a>
                    <span class="paren6">(<span class="code">unstash-all</span>)</span>
                    <span class="paren6">(<span class="code">become <span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren2">(<span class="code">msg</span>)</span>
                              <span class="paren2">(<span class="code">case msg
                                <span class="paren3">(<span class="code"><span class="keyword">:write</span>
                                 <span class="comment">;; do something
</span>                                 </span>)</span>
                                <span class="paren3">(<span class="code"><span class="keyword">:close</span>
                                 <span class="paren4">(<span class="code">unbecome</span>)</span></span>)</span>
                                <span class="paren3">(<span class="code">otherwise
                                 <span class="paren4">(<span class="code">stash msg</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
                 <span class="paren4">(<span class="code">otherwise <span class="paren5">(<span class="code">stash msg</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<h4>Stashing messages</h4>
<p>Stashing allows the actor to <code>stash</code> away messages for when the actor is in a state that doesn't allow it to handle certain messages. <code>unstash-all</code> can unstash all stashed messages.</p>
<p>See: API <a href="https://mdbergmann.github.io/cl-gserver/index.html#SENTO.STASH:STASHING%20CLASS" >documentation</a> for more info.</p>
<h4>Creating actors without a system</h4>
<p>It is still possible to create actors without a system. This is how you do it:</p>
<pre><code><span class="code"><span class="comment">;; make an actor
</span><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_143.html#IDX430" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*my-actor*</span> <span class="paren2">(<span class="code">act:make-actor <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code">msg</span>)</span>
                                     <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"FooBar"</span></span>)</span></span>)</span>
                                   <span class="keyword">:name</span> <span class="string">"Lone-actor"</span></span>)</span></span>)</span>
<span class="comment">;; setup a thread based message box
</span><span class="paren1">(<span class="code">setf <span class="paren2">(<span class="code">act-cell:msgbox <span class="special">*my-actor*</span></span>)</span> 
      <span class="paren2">(<span class="code">make-instance 'mesgb:message-box/bt</span>)</span></span>)</span></span></code></pre>
<p>You have to take care yourself about stopping the actor and freeing resources.</p>
<h3>Agents</h3>
<p>An Agent is a specialized Actor. It is meant primarily for maintaining state and comes with some conveniences to do that.</p>
<p>To use an Agent import <code>sento.agent</code> package.</p>
<p>There is no need to subclass an Agent. Rather create a facade to customize an agent. See below.</p>
<p>An Agent provides three functions to use it.</p>
<ul>
<li><code>make-agent</code> creates a new agent. Optionally specify an <code>actor-context</code> or define the kind of dispatcher the agent should use.</li>
<li><code>agent-get</code> retrieves the current state of the agent. This directly delivers the state of the agent for performance reasons. There is no message handling involved.</li>
<li><code>agent-update</code> updates the state of the agent</li>
<li><code>agent-update-and-get</code> updates the agent state and returns the new state.</li>
</ul>
<p>All four take a lambda. The lambda for <code>make-agent</code> does not take a parameter. It should return the initial state of the agent. <code>agent-get</code> and <code>agent-update</code> both take a lambda that must support one parameter.
This parameter represents the current state of the agent.</p>
<p>Let's make a simple example:</p>
<p>First create an agent with an initial state of <code>0</code>.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*my-agent*</span> <span class="paren2">(<span class="code">make-agent <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span> 0</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Now update the state several times (<code>agent-update</code> is asynchronous and returns <code>t</code> immediately):</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">agent-update <span class="special">*my-agent*</span> <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">state</span>)</span> <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX103" class="symbol">1+</a> state</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Finally get the state:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">agent-get <span class="special">*my-agent*</span> #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_168.html#IDX488" class="symbol">identity</a></span>)</span></span></code></pre>
<p>This <code>agent-get</code> just uses the <code>identity</code> function to return the state as is.</p>
<p>So this simple agent represents a counter.</p>
<p>It is important to note that the retrieves state, i.e. with <code>identity</code> should not be modified outside the agent.</p>
<h4>Using an agent within an actor-system</h4>
<p>The <code>make-agent</code> constructor function allows to provide an optional <code>actor-context</code> argument that, when given, makes the constructor create the agent within the given actor-context. Another parameter <code>dispatcher-id</code> allows to specify the dispatcher where <code>:shared</code> is the default, <code>:pinned</code> will create the agent with a separate mailbox thread.</p>
<p>It also implies that the agent is destroyed then the actor-system is destroyed.</p>
<p>However, while actors can create hierarchies, agents can not. Also the API for creating agents in systems is different to actors. This is to make explicit that agents are treated slightly differently than actors even though under the hood agents are actors.</p>
<h4>Wrapping an agent</h4>
<p>While you can use the agent as in the example above it is usually advised to wrap an agent behind a more simple facade that doesn't work with lambdas and allows a more domain specific naming.</p>
<p>For example could a facade for the counter above look like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_143.html#IDX430" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*counter-agent*</span> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_6.html#SEC6" class="symbol">nil</a></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> init-agent <span class="paren2">(<span class="code">initial-value</span>)</span>
  <span class="paren2">(<span class="code">setf <span class="special">*counter-agent*</span> <span class="paren3">(<span class="code">make-agent <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="code"></span>)</span> initial-value</span>)</span></span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> increment <span class="paren2">(<span class="code"></span>)</span> <span class="paren2">(<span class="code">agent-update <span class="special">*counter-agent*</span> #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX103" class="symbol">1+</a></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> decrement <span class="paren2">(<span class="code"></span>)</span> <span class="paren2">(<span class="code">agent-update <span class="special">*counter-agent*</span> #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX104" class="symbol">1-</a></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> counter-value <span class="paren2">(<span class="code"></span>)</span> <span class="paren2">(<span class="code">agent-get <span class="special">*counter-agent*</span> #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_168.html#IDX488" class="symbol">identity</a></span>)</span></span>)</span></span></code></pre>
<p>Alternatively, one can wrap an agent inside a class and provide methods for simplified access to it.</p>
<h3>Finite State Machine (FSM)</h3>
<p>The Finite State Machine (FSM) model is a computational framework designed to model and manage systems that transition between various states based on inputs or events. This structured approach facilitates the handling of complex logic through defined state transitions and events.</p>
<h4>Creating an FSM</h4>
<p>To create an FSM, use the <code>make-fsm</code> function, which initializes an actor with state management capabilities.</p>
<p>(Additional API documentation can be found <a href="https://mdbergmann.github.io/cl-gserver/index.html##SENTO.FSM:@FSM%20MGL-PAX:SECTION" >here</a>.)</p>
<ol>
<li><strong>actor-context</strong>: Specifies where the FSM is created, which can be an actor, an actor-context, or an actor-system.</li>
<li><strong>name</strong>: A string that names the FSM.</li>
<li><strong>start-with</strong>: A cons cell representing the initial state and associated data.</li>
<li><strong>event-handling</strong>: A function structured using FSM macros to define the FSM's behavior upon receiving events.</li>
</ol>
<h4>Example: Traffic Light Controller FSM with Timeouts</h4>
<p>This FSM simulates a traffic light controller and includes comprehensive state and transition handling, including timeouts.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> make-traffic-light-fsm <span class="paren2">(<span class="code">actor-context</span>)</span>
  <span class="paren2">(<span class="code">make-fsm
   actor-context
   <span class="keyword">:name</span> <span class="string">"traffic-light-fsm"</span>
   <span class="keyword">:start-with</span> '<span class="paren3">(<span class="code">red . <span class="paren4">(<span class="code"></span>)</span></span>)</span>
   <span class="keyword">:event-handling</span> <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span>

                     <span class="comment">;; Define behavior in each state using when-state
</span>                     <span class="paren4">(<span class="code">when-state <span class="paren5">(<span class="code">'red <span class="keyword">:timeout-s</span> 10</span>)</span>
                       <span class="paren5">(<span class="code">on-event <span class="paren6">(<span class="code">'timer</span>)</span> <span class="keyword">:state-timeout</span>
                         <span class="paren6">(<span class="code">goto-state 'green</span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">on-event <span class="paren6">(<span class="code">'manual-override</span>)</span>
                         <span class="paren6">(<span class="code">stay-on-state '<span class="paren1">(<span class="code"><span class="keyword">:manual-override-engaged</span></span>)</span></span>)</span>
                         <span class="paren6">(<span class="code">log:info <span class="string">"Manual override activated"</span></span>)</span></span>)</span></span>)</span>

                     <span class="paren4">(<span class="code">when-state <span class="paren5">(<span class="code">'green <span class="keyword">:timeout-s</span> 15</span>)</span>
                       <span class="paren5">(<span class="code">on-event <span class="paren6">(<span class="code">'timer</span>)</span> <span class="keyword">:state-timeout</span>
                         <span class="paren6">(<span class="code">goto-state 'yellow</span>)</span></span>)</span></span>)</span>

                     <span class="paren4">(<span class="code">when-state <span class="paren5">(<span class="code">'yellow <span class="keyword">:timeout-s</span> 5</span>)</span>
                       <span class="paren5">(<span class="code">on-event <span class="paren6">(<span class="code">'emergency-stop</span>)</span>
                         <span class="paren6">(<span class="code">goto-state 'red</span>)</span>
                         <span class="paren6">(<span class="code">log:info <span class="string">"Emergency stop activated"</span></span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">on-event <span class="paren6">(<span class="code">'timer</span>)</span> <span class="keyword">:state-timeout</span>
                         <span class="paren6">(<span class="code">goto-state 'red</span>)</span></span>)</span></span>)</span>

                     <span class="comment">;; Handle state transitions
</span>                     <span class="paren4">(<span class="code">on-transition <span class="paren5">(<span class="code">'<span class="paren6">(<span class="code">red . green</span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">log:info <span class="string">"Transition from red to green"</span></span>)</span></span>)</span>

                     <span class="paren4">(<span class="code">on-transition <span class="paren5">(<span class="code">'<span class="paren6">(<span class="code">green . yellow</span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">log:info <span class="string">"Transition from green to yellow"</span></span>)</span></span>)</span>

                     <span class="paren4">(<span class="code">on-transition <span class="paren5">(<span class="code">'<span class="paren6">(<span class="code">yellow . red</span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">log:info <span class="string">"Transition from yellow to red"</span></span>)</span></span>)</span>

                     <span class="comment">;; Stay on current state but update data
</span>                     <span class="paren4">(<span class="code">on-event <span class="paren5">(<span class="code">'maintenance-check</span>)</span>
                       <span class="paren5">(<span class="code">stay-on-state '<span class="paren6">(<span class="code"><span class="keyword">:maintenance-required</span></span>)</span></span>)</span>
                       <span class="paren5">(<span class="code">log:info <span class="string">"Maintenance required"</span></span>)</span></span>)</span>

                     <span class="comment">;; Handle unhandled events with specific and general catch
</span>                     <span class="paren4">(<span class="code">when-unhandled <span class="paren5">(<span class="code">'unexpected-event</span>)</span>
                       <span class="paren5">(<span class="code">log:warn <span class="string">"Unexpected specific event caught"</span></span>)</span></span>)</span>

                     <span class="paren4">(<span class="code">when-unhandled <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="keyword">:test</span> #'typep</span>)</span>
                       <span class="paren5">(<span class="code">log:warn <span class="string">"Unhandled event caught: ~A"</span> <span class="special">*received-event*</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<h4>Example Breakdown</h4>
<ul>
<li><strong>actor-context</strong>: Passed argument where the FSM operates.</li>
<li><strong>name</strong>: The FSM is named &quot;traffic-light-fsm&quot;.</li>
<li><strong>start-with</strong>: The FSM begins in the 'red' state.</li>
<li><strong>event-handling</strong>: Utilizes various macros:</li>
<li><code>when-state</code>: Defines actions specific to each state and handles timeouts.</li>
<li><code>on-event ('timer)</code>: Transitions the FSM to the next state on timer events; handles timeouts with <code>:state-timeout</code>.</li>
<li><code>goto-state</code>: Transitions the FSM to a new state, optionally updating data and logging.</li>
<li><code>stay-on-state ('maintenance-check)</code>: Remains in the current state while updating state data.</li>
<li><code>on-transition</code>: Logs state transitions.</li>
<li>General <code>when-unhandled</code> using <code>typep</code>: Catches all other unhandled events and logs them using the dynamic variable <code>*received-event*</code> for context.</li>
</ul>
<h4>Running the FSM</h4>
<p>After setup, the FSM processes events, transitioning as defined. This setup ensures responsive and structured event-driven state management.</p>
<p>Incorporating timeout controls and a comprehensive fallback for unhandled events, this FSM elegantly manages complex state logic with powerful macro functionalities.</p>
<h3>Router</h3>
<p>A <code>Router</code> is a facade over a set of actors. Routers are either created with a set of actors using the default constructor <code>router:make-router</code> or actors can be added later.</p>
<p>Routers implement part of the actor protocol, so it allows to use <code>tell</code>, <code>ask-s</code> or <code>ask</code> which it forwards to a 'routee' (one of the actors of a router) by passing all of the given parameters. The routee is chosen by applying a <code>strategy</code>. The built-in default strategy a routee is chosen randomly.</p>
<p>The <code>strategy</code> can be configured when creating a router using the constructors <code>&amp;key</code> parameter <code>:strategy</code>. The <code>strategy</code> is just a function that takes the number of routees and returns a routee index to be chosen for the next operation.</p>
<p>Currently available strategies: <code>:random</code> and<code>:round-robin</code>.</p>
<p>Custom strategies can be implemented.</p>
<h3>Dispatchers</h3>
<h4>:shared</h4>
<p>A <code>:shared</code> dispatcher is a facility that is set up in the <code>actor-system</code>. It consists of a configurable pool of 'dispatcher workers' (which are in fact actors). Those dispatcher workers execute the message handling in behalf of the actor and with the actors message handling code. This is protected by a lock so that ever only one dispatcher will run code on an actor. This is to ensure protection from data race conditions of the state data of the actor (or other slots of the actor).</p>
<p>Using this dispatcher allows to create a large number of actors. The actors as such are generally very cheap.</p>
<p><img alt="" src="./docs/disp_shared.png" width="700"/>
<img alt="" src="disp_shared.png" width="700"/></p>
<h4>:pinned</h4>
<p>The <code>:pinned</code> dispatcher is represented by just a thread that operates on the actors message queue. It handles one message after another with the actors message handling code. This also ensures protection from data race conditions of the state of the actor.</p>
<p>This variant is slightly faster (see below) but requires one thread per actor.</p>
<p><img alt="" src="./docs/disp_pinned.png" width="700"/>
<img alt="" src="disp_pinned.png" width="700"/></p>
<h4>custom dispatcher</h4>
<p>It is possible to create additional dispatcher of type <code>:shared</code>. A name can be freely chosen, but by convention it should be a global symbol, i.e. <code>:my-dispatcher</code>.</p>
<p>When creating actors using <code>act:actor-of</code>, or when using the <code>tasks</code> API it is possible to specify the dispatcher (via the 'dispatcher-id' i.e. <code>:my-dispatcher</code>) that should handle the actor, agent, or task messages.</p>
<p>A custom dispatcher is in particular useful when using <code>tasks</code> for longer running operations. Longer running operations should not be used for the <code>:shared</code> dispatcher because it is, by default, responsible for the message handling of most actors.</p>
<h3>Eventstream</h3>
<p>The eventstream allows messages (or events) to be posted on the eventstream in a fire-and-forget kind of way. Actors can subscribe to the eventstream if they want to get notified for particular messages or any message posted to the event stream.<br/>
This allows to create event-based systems.</p>
<p>Here is a simple example:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">asys:make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code">ac:actor-of <span class="special">*sys*</span> <span class="keyword">:name</span> <span class="string">"listener"</span>
  <span class="keyword">:init</span> <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">self</span>)</span>
          <span class="paren3">(<span class="code">ev:subscribe self self '<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_71.html#IDX149" class="symbol">string</a></span>)</span></span>)</span>
  <span class="keyword">:receive</span> <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">msg</span>)</span>
             <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_126.html#IDX389" class="symbol"><i><span class="symbol">cond</span></i></a>
               <span class="paren4">(<span class="code"><span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_73.html#IDX157" class="symbol">string=</a> <span class="string">"my-message"</span> msg</span>)</span>
                <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_75.html#IDX176" class="symbol">format</a> <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_266.html#IDX704" class="symbol">t</a> <span class="string">"received event: ~a~%"</span> msg</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code">ev:publish <span class="special">*sys*</span> <span class="string">"my-message"</span></span>)</span></span></code></pre>
<p>This subscribes to all <code>'string</code> based events and just prints the message when received.<br/>
The subscription here is done using the <code>:init</code> hook of the actor. The <code>ev:subscribe</code> function requires to specify the eventstream as first argument. But there are different variants of the generic function defined which allows to specify an actor directly. The eventstream is retrieve from the actor through its actor-context.</p>
<pre><code><span class="code">received event: my-message</span></code></pre>
<p>See the API <a href="https://mdbergmann.github.io/cl-gserver/index.html#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" >documentation</a> for more details.</p>
<h3>Tasks</h3>
<p>'tasks' is a convenience package that makes dealing with asynchronous and concurrent operations very easy.</p>
<p>Here is a simple example:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  
  // run something without requiring a feedback
  <span class="paren2">(<span class="code">task-start <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span> <span class="paren4">(<span class="code">do-lengthy-IO</span>)</span></span>)</span>
  
  // run asynchronous <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX106" class="symbol">-</a> with await
  <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">task <span class="paren6">(<span class="code">task-async <span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren2">(<span class="code"></span>)</span> <span class="paren2">(<span class="code">do-a-task</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
    // do some other stuff
    // eventually we need <i><span class="symbol">the</span></i> task result
    <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a> <span class="paren5">(<span class="code">task-await task</span>)</span> 5</span>)</span></span>)</span>
    
  // run asynchronous with completion-handler <span class="paren3">(<span class="code">continuation</span>)</span>
  <span class="paren3">(<span class="code">task-async <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="code"></span>)</span> <span class="paren5">(<span class="code">some-bigger-computation</span>)</span></span>)</span>
              <span class="keyword">:on-complete-fun</span>
              <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="code">result</span>)</span>
                <span class="paren5">(<span class="code">do-something-with result</span>)</span></span>)</span></span>)</span>

  // concurrently map over <i><span class="symbol">the</span></i> given <a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_83.html#IDX225" class="symbol">list</a>
  <span class="paren3">(<span class="code">-&gt;&gt; 
    '<span class="paren4">(<span class="code">1 2 3 4 5</span>)</span>
    <span class="paren4">(<span class="code">task-async-stream #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX103" class="symbol">1+</a></span>)</span>
    <span class="paren4">(<span class="code">reduce #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a></span>)</span></span>)</span></span>)</span>

=&gt; 20 <span class="paren2">(<span class="code">5 bits, #x14, #o24, #b10100</span>)</span>
</span></span></span></code></pre>
<p>All functions available in 'tasks' package require to be wrapped in a <code>with-context</code> macro. This macro removes the necessity of an additional argument to each of the functions which is instead supplied by the macro.</p>
<p>What happens in the example above is that the list <code>'(1 2 3 4 5)</code> is passed to <code>task-async-stream</code>. <code>task-async-stream</code> then spawns a 'task' for each element of the list and applies the given function (here <code>1+</code>) on each list element. The function though is executed by a worker of the actor-systems <code>:shared</code> dispatcher. <code>task-async-stream</code> then also collects the result of all workers. In the last step (<code>reduce</code>) the sum of the elements of the result list are calculated.</p>
<p>It is possible to specify a second argument to the <code>with-context</code> macro to specify the dispatcher that should be used for the tasks.<br/>
The concurrency here depends on the number of dispatcher workers.</p>
<p>As alternative, or in special circumstances, it is possible to setf <code>*task-context*</code> and/or <code>*task-dispatcher*</code> special variables which allows to use <strong>tasks</strong> without <code>with-context</code> macro.</p>
<p>Be also aware that the <code>:shared</code> dispatcher should not run long running operations as it blocks a message processing thread. Create a custom dispatcher to use for <code>tasks</code> when you plan to operate longer running operations.</p>
<p>See the API <a href="https://mdbergmann.github.io/cl-gserver/index.html#SENTO.TASKS:WITH-CONTEXT%20MGL-PAX:MACRO" >documentation</a> for more details.</p>
<h3>Immutability</h3>
<p>Some words on immutability. Actor states don't need to be immutable data structures. Sento does <em>not</em> make copies of the actor states. The user is responsible for the actor state and to motate the actor state only within 'receive' function.</p>
<h3>Logging</h3>
<p>Sento does its own logging using different log levels from 'trace' to 'error' using log4cl. If you wish to also use log4cl in your application but find that Sento is too noisy in debug and trace logging you can change the log level for the 'sento package only by:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">log:config '<span class="paren2">(<span class="code">sento</span>)</span> <span class="keyword">:warn</span></span>)</span></span></code></pre>
<p>This will tell log4cl to do any logging for sento in warn level.</p>
<h3>Benchmarks</h3>
<p>Hardware specs (M1)):</p>
<ul>
<li>Mac M1 Ultra, 64 GB RAM</li>
</ul>
<p><img src="./docs/perf-M1Ultra.png" alt="" />
<img src="perf-M1Ultra.png" alt="" /></p>
<p>Hardware specs (x86-64):</p>
<ul>
<li>iMac Pro (2017), 8 Core Xeon, 32 GB RAM</li>
</ul>
<p><img src="./docs/perf-x86_64.png" alt="" />
<img src="perf-x86_64.png" alt="" /></p>
<p><strong>All</strong></p>
<p>Version 3.2.0 of Sento uses the sbcl <code>sb-concurrent:queue</code> whcih is very fast and works using CAS (compare-and-swap) where as the other implementations use a still fast double stack queue protected by locking.</p>
<p>The benchmark was created by having 8 threads throwing each 125k (1M altogether) messages at 1 actor. The timing was taken for when the actor did finish processing those 1M messages. The messages were sent by either all <code>tell</code>, <code>ask-s</code>, or <code>ask</code> to an actor whose message-box worked using a single thread (<code>:pinned</code>) or a dispatched message queue (<code>:shared</code> / <code>dispatched</code>) with 8 workers.</p>
<p>Of course a <code>tell</code> is in most cases the fastest one, because it's the least resource intensive and there is no place that is blocking in this workflow.</p>
<p><strong>SBCL (v2.4.1)</strong></p>
<p>SBCL is very fast, but this tests uses SBCLs own queue implementation based on CAS instead of locking.</p>
<p><strong>LispWorks (8.0.1)</strong></p>
<p>LispWorks is fast overall. Not as fast as SBCL. But it seems the GC is more robust, in particular on the <code>dispatched - ask</code>.</p>
<p><strong>CCL (v1.12)</strong></p>
<p>Unfortunately CCL doesn't work natively on M1 Apple CPU.</p>
<p><strong>ABCL (1.9)</strong></p>
<p>The pleasant surprise was ABCL. While not being the fastest it is very robust.</p>
<p><strong>Clasp 2.5.0</strong></p>
<p>Very slow. Used default settings, as also for the other tests.
Maybe something can be tweaked?</p>
<h3>Migration guide for moving from Sento 2 to Sento 3</h3>
<ul>
<li><p>the receive function is now 1-arity. It only takes the a message parameter.
Previous 'self' and 'state' parameters are now accessible via <code>*self*</code> and <code>*state*</code>. The same applies to <code>become</code> function.</p></li>
<li><p>the return value of 'receive' function has always been a bit of an obstacle. So now it is ignored for <code>tell</code> and <code>ask</code>. In both cases a <code>reply</code> function can be used to reply to a sender. <code>reply</code> implicitly uses <code>*sender*</code> but can be overriden (see 'long running and asynchronous operations in receive'). The 'receive' function return value is still relevant for <code>ask-s</code>, but now it doesn't need to be a <code>cons</code>. Whatever is returned is received by <code>ask-s</code>.</p></li>
<li><p>'utils' package has been split to 'timeutils' for i.e. ask-timeout condition, and 'miscutils' for i.e. filter function.</p></li>
</ul>
<h3>Version history</h3>
<p><strong>Version 3.3.3 (1.10.2024):</strong> Bug fix for actor with dispatcher mailbox where the order of processing messages wasn't honoured.</p>
<p><strong>Version 3.3.2 (14.8.2024):</strong> Primarily documentation changes in regards to <code>future</code></p>
<p><strong>Version 3.3.0 (1.7.2024):</strong> See: <a href="https://github.com/mdbergmann/cl-gserver/compare/3.2.1...3.3.0" >Changelog</a></p>
<p><strong>Version 3.2.0 (13.2.2024):</strong> Message-box queue changes. SBCL now uses a separate fast CAS based queue coming as a contrib package. The other impls use a faster queue by default but still with locking. New benchmarks.</p>
<p><strong>Version 3.1.0 (14.1.2024):</strong> Added scheduler facility to actor-system that allows to schedule functions one or recurring. See API documentation for more info.</p>
<p><strong>Version 3.0.4 (10.7.2023):</strong> Allow additional initialization arguments be passed to actor. Wheel-time now knows CANCEL function. Partial fix for clasp (2.3.0).</p>
<p><strong>Version 3.0.3 (1.4.2023):</strong> Minor implementation changes regarding pre-start and after-stop.</p>
<p><strong>Version 3.0.2 (6.4.2023):</strong> Fix for actor stopping with 'wait'.</p>
<p><strong>Version 3.0.0 (1.2.2023):</strong> New major version. See migration guide if you have are migrating from version 2.</p>
<p><strong>Version 2.2.0 (27.12.2022):</strong> Added stashing and unstashing of messages.</p>
<p><strong>Version 2.1.0 (17.11.2022):</strong> Reworked the <code>future</code> package. Nicer syntax and futures can now be mapped.</p>
<p><strong>Version 2.0.0 (16.8.2022):</strong> Rename to &quot;Sento&quot;. Incompatible change due to package names and system have changed.</p>
<p><strong>Version 1.12.2 (29.5.2022):</strong> Removed the logging abstraction again. Less code to maintain. log4cl is featureful enough for users to either use it, or use something else in the applications that are based on sento.</p>
<p><strong>Version 1.12.1 (25.5.2022):</strong> Shutdown and stop of actor, actor context and actor system can now wait for a full shutdown/stop of all actors to really have a clean system shutdown.</p>
<p><strong>Version 1.12.0 (26.2.2022):</strong> Refactored and cleaned up the available <code>actor-of</code> facilities. There is now only one. If you used the macro before, you may have to adapt slightly.</p>
<p><strong>Version 1.11.1 (25.2.2022):</strong> Minor additions to <code>actor-of</code> macro to allow specifying a <code>destroy</code> function.</p>
<p><strong>Version 1.11.0 (16.1.2022):</strong> Changes to <code>AC:FIND-ACTORS</code>. Breaking API change. See API documentation for details.</p>
<p><strong>Version 1.10.0:</strong> Logging abstraction. Use your own logging facility. sento doesn't lock you in but provides support for log4cl. Support for other logging facilities can be easily added so that the logging of sento  will use your chosen logging library. See below for more details.</p>
<p><strong>Version 1.9.0:</strong> Use wheel timer for <code>ask</code> timeouts.</p>
<p><strong>Version 1.8.2:</strong> atomic add/remove of actors in actor-context.</p>
<p><strong>Version 1.8.0:</strong> hash-agent interface changes. Added array-agent.</p>
<p><strong>Version 1.7.6:</strong> Added cl:hash-table based agent with similar API interface.</p>
<p><strong>Version 1.7.5:</strong> Allow agent to specify the dispatcher to be used.</p>
<p><strong>Version 1.7.4:</strong> more convenience additions for task-async (completion-handler)</p>
<p><strong>Version 1.7.3:</strong> cleaned up dependencies. Now sento works on SBCL, CCL, LispWorks, Allegro and ABCL</p>
<p><strong>Version 1.7.2:</strong> allowing to choose the dispatcher strategy via configuration</p>
<p><strong>Version 1.7.1:</strong> added possibility to create additional and custom dispatchers. I.e. to be used with <code>tasks</code>.</p>
<p><strong>Version 1.7.0:</strong> added tasks abstraction facility to more easily deal with asynchronous and concurrent operations.</p>
<p><strong>Version 1.6.0:</strong> added eventstream facility for building event based systems. Plus documentation improvements.</p>
<p><strong>Version 1.5.0:</strong> added configuration structure. actor-system can now be created with a configuration. More configuration options to come.</p>
<p><strong>Version 1.4.1:</strong> changed documentation to the excellent <a href="https://github.com/melisgl/mgl-pax" >mgl-pax</a></p>
<p><strong>Version 1.4:</strong> convenience macro for creating actor. See below for more details</p>
<p><strong>Version 1.3.1:</strong> round-robin strategy for router</p>
<p><strong>Version 1.3:</strong> agents can be created in actor-system</p>
<p><strong>Version 1.2:</strong> introduces a breaking change</p>
<p><code>ask</code> has been renamed to <code>ask-s</code>.</p>
<p><code>async-ask</code> has been renamed to <code>ask</code>.</p>
<p>The proposed default way to query for a result from another actor should
be an asynchronous <code>ask</code>. <code>ask-s</code> (synchronous) is
of course still possible.</p>
<p><strong>Version 1.0</strong> of <code>sento</code> library comes with quite a
few new features (compared to the previous 0.x versions). 
One of the major new features is that an actor is not
bound to it's own message dispatcher thread. Instead, when an
<code>actor-system</code> is set-up, actors can use a shared pool of
message dispatchers which effectively allows to create millions of
actors.</p>
<p>It is now possible to create actor hierarchies. An actor can have child
actors. An actor now can also 'watch' another actor to get notified
about it's termination.</p>
<p>It is also possible to specify timeouts for the <code>ask-s</code> and
<code>ask</code> functionality.</p>
<p>This new version is closer to Akka (the actor model framework on the
JVM) than to GenServer on Erlang. This is because Common Lisp from a
runtime perspective is closer to JVM than to Erlang/OTP. Threads in
Common Lisp are heavy weight OS threads rather than user-space low
weight 'Erlang' threads (I'd like to avoid 'green threads', because
threads in Erlang are not really green threads). While on Erlang it is
easily possible to spawn millions of processes/threads and so each actor
(GenServer) has its own process, this model is not possible when the
threads are OS threads, because of OS resource limits. This is the main
reason for working with the message dispatcher pool instead.</p>
<p><a id="x-28SENTO-2EDOCS-3A-40API-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.DOCS:@API%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.DOCS:@README%20MGL-PAX:SECTION" title="Introduction">&#8592;</a> <a href="sento.html" title="sento documentation">&#8593;</a> <a href="#SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION" title="Actor-System">&#8594;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8634;</a></span></span></p>
<h2><a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION">2 API documentation</a></h2>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3A-40ACTOR-SYSTEM-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION" title="Actor-Context">&#8594;</a> <a href="#SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION" title="Actor-System">&#8634;</a></span></span></p>
<h3><a href="#SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION">2.1 Actor-System</a></h3>
<h6>[in package SENTO.ACTOR-SYSTEM with nicknames ASYS]</h6>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20CLASS-29"></a>
<a id="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" >ACTOR-SYSTEM</a></span></span></span></p>

<p>An <code>actor-system</code> is the opening facility. The first thing you do is to create an <code>actor-system</code> using the main constructor <a href="#SENTO.ACTOR-SYSTEM:MAKE-ACTOR-SYSTEM%20FUNCTION" title="SENTO.ACTOR-SYSTEM:MAKE-ACTOR-SYSTEM FUNCTION"><code>make-actor-system</code></a>.
With the <code>actor-system</code> you can create actors via the <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol function: <a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20GENERIC-FUNCTION" title="SENTO.ACTOR-CONTEXT:ACTOR-OF GENERIC-FUNCTION"><code>ac:actor-of</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3AMAKE-ACTOR-SYSTEM-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-SYSTEM:MAKE-ACTOR-SYSTEM%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:MAKE-ACTOR-SYSTEM%20FUNCTION" >MAKE-ACTOR-SYSTEM</a></span></span> <span class="locative-args">&amp;OPTIONAL CONFIG</span></span></p>

<p>Creates an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>actor-system</code></a>.</p>

<p>Allows to provide an optional configuration. See <a href="#SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE" title="SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG* VARIABLE"><code>asys:*default-config*</code></a>.
If no config is provided the default config is used.
Is a config provided then it is merged with the default config.
Config options in the existing config override the default config.
See <a href="#SENTO.CONFIG:CONFIG-FROM%20FUNCTION" title="SENTO.CONFIG:CONFIG-FROM FUNCTION"><code>config:config-from</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3A-2ADEFAULT-CONFIG-2A-20VARIABLE-29"></a>
<a id="SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE" >*DEFAULT-CONFIG*</a></span></span> <span class="locative-args">(:DISPATCHERS (:SHARED (:WORKERS 4 :STRATEGY :RANDOM)) :TIMEOUT-TIMER
 (:RESOLUTION 500 :MAX-SIZE 1000) :EVENTSTREAM (:DISPATCHER-ID :SHARED)
 :SCHEDULER (:ENABLED :TRUE :RESOLUTION 100 :MAX-SIZE 500))</span></span></p>

<p>The default config used when creating an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>.
The actor-system constructor allows to provide custom config options that override the default.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3AREGISTER-DISPATCHER-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-SYSTEM:REGISTER-DISPATCHER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:REGISTER-DISPATCHER%20FUNCTION" >REGISTER-DISPATCHER</a></span></span> <span class="locative-args">SYSTEM DISPATCHER</span></span></p>

<p>Registers a dispatcher to the actor-system.</p>

<ul>
<li><p><code>system</code>: the actor-system</p></li>
<li><p><code>dispatcher</code>: the dispatcher instance.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3AREGISTER-NEW-DISPATCHER-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-SYSTEM:REGISTER-NEW-DISPATCHER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:REGISTER-NEW-DISPATCHER%20FUNCTION" >REGISTER-NEW-DISPATCHER</a></span></span> <span class="locative-args">SYSTEM DISPATCHER-ID &amp;KEY WORKERS STRATEGY</span></span></p>

<p>Makes and registers a new dispatcher.</p>

<ul>
<li><p><code>system</code>: the actor-system</p></li>
<li><p><code>dispatcher-id</code>: the dispatcher identifier. Usually a global symbol like <code>:foo</code></p></li>
<li><p><code>:workers</code>: key argument for the number of workers.</p></li>
<li><p><code>:strategy</code>: key argument for the dispatcher strategy (:random or :round-robin)</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3AEVSTREAM-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-29-29"></a>
<a id="SENTO.ACTOR-SYSTEM:EVSTREAM%20%28MGL-PAX:READER%20SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:EVSTREAM%20%28MGL-PAX:READER%20SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29" >EVSTREAM</a></span></span> <span class="locative-args">ACTOR-SYSTEM (= NIL)</span></span></p>

<p>The system event stream. See <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> for more info.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-SYSTEM-3ASCHEDULER-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-29-29"></a>
<a id="SENTO.ACTOR-SYSTEM:SCHEDULER%20%28MGL-PAX:READER%20SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-SYSTEM:SCHEDULER%20%28MGL-PAX:READER%20SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29" >SCHEDULER</a></span></span> <span class="locative-args">ACTOR-SYSTEM (= NIL)</span></span></p>

<p>A general purpose scheduler that can be used by actors.
See <a href="#SENTO.WHEEL-TIMER:WHEEL-TIMER%20CLASS" title="SENTO.WHEEL-TIMER:WHEEL-TIMER CLASS"><code>wt:wheel-timer</code></a> for more info.</p>

<p>The scheduler defaults to a resolution of 100 milliseconds and a maximum of 500 entries.</p>

<p>It is possible to disable the scheduler, i.e. to safe a thread resource, by setting the <code>:enabled</code> key to <code>:false</code> in the <code>:scheduler</code> section of the configuration.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-OF-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29" >SENTO.ACTOR-CONTEXT:ACTOR-OF</a></span></span> <span class="locative-args">(SYSTEM <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ACTOR-SYSTEM</code></a>)</span></span></p>

<p>See <code>ac:actor-of</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AFIND-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20T-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29" >SENTO.ACTOR-CONTEXT:FIND-ACTORS</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ACTOR-SYSTEM</code></a>) PATH</span></span></p>

<p>See <code>ac:find-actors</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AALL-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29" >SENTO.ACTOR-CONTEXT:ALL-ACTORS</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ACTOR-SYSTEM</code></a>)</span></span></p>

<p>See <code>ac:all-actors</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASTOP-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20T-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:STOP%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:STOP%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29" >SENTO.ACTOR-CONTEXT:STOP</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ACTOR-SYSTEM</code></a>) ACTOR</span></span></p>

<p>See <code>ac:stop</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASHUTDOWN-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:SHUTDOWN%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:SHUTDOWN%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29%29" >SENTO.ACTOR-CONTEXT:SHUTDOWN</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ACTOR-SYSTEM</code></a>)</span></span></p>

<p>See <code>ac:shutdown</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3A-40ACTOR-CONTEXT-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ACTOR-SYSTEM:@ACTOR-SYSTEM%20MGL-PAX:SECTION" title="Actor-System">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION" title="Actor-Context protocol">&#8594;</a> <a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION" title="Actor-Context">&#8634;</a></span></span></p>
<h3><a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION">2.2 Actor-Context</a></h3>
<h6>[in package SENTO.ACTOR-CONTEXT with nicknames AC]</h6>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-20CLASS-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" >ACTOR-CONTEXT</a></span></span></span></p>

<p><code>actor-context</code> deals with creating and maintaining actors.
The <code>actor-system</code> and the <code>actor</code> itself are composed of an <code>actor-context</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AMAKE-ACTOR-CONTEXT-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:MAKE-ACTOR-CONTEXT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:MAKE-ACTOR-CONTEXT%20FUNCTION" >MAKE-ACTOR-CONTEXT</a></span></span> <span class="locative-args">ACTOR-SYSTEM &amp;OPTIONAL (ID <code>NIL</code>)</span></span></p>

<p>Creates an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>actor-context</code></a>. Requires a reference to <code>actor-system</code>
<code>id</code> is an optional value that can identify the <code>actor-context</code>.
Creating an actor-context manually is usually not needed.
An <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> implements the <code>actor-context</code> protocol.
An <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>act:actor</code></a> contains an <code>actor-context</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-OF-20-28METHOD-20NIL-20-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29" >ACTOR-OF</a></span></span> <span class="locative-args">(CONTEXT <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ACTOR-CONTEXT</code></a>)</span></span></p>

<p>See <code>ac:actor-of</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AFIND-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-20T-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20T%29%29" >FIND-ACTORS</a></span></span> <span class="locative-args">(CONTEXT <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ACTOR-CONTEXT</code></a>) PATH</span></span></p>

<p>See <code>ac:find-actors</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AALL-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29" >ALL-ACTORS</a></span></span> <span class="locative-args">(CONTEXT <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ACTOR-CONTEXT</code></a>)</span></span></p>

<p>See <code>ac:all-actors</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASTOP-20-28METHOD-20NIL-20-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-20T-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:STOP%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:STOP%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20T%29%29" >STOP</a></span></span> <span class="locative-args">(CONTEXT <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ACTOR-CONTEXT</code></a>) ACTOR</span></span></p>

<p>See <code>ac:stop</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASHUTDOWN-20-28METHOD-20NIL-20-28SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:SHUTDOWN%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:SHUTDOWN%20%28METHOD%20NIL%20%28SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29%29" >SHUTDOWN</a></span></span> <span class="locative-args">(CONTEXT <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ACTOR-CONTEXT</code></a>)</span></span></p>

<p>See <code>ac:shutdown</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ANOTIFY-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:NOTIFY%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:NOTIFY%20GENERIC-FUNCTION" >NOTIFY</a></span></span> <span class="locative-args">CONTEXT ACTOR NOTIFICATION</span></span></p>

<p>Notify the <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>actor-context</code></a> about something that happened to an actor.
Current exists:</p>

<ul>
<li><code>:stopped</code>: this will remove the actor from the context.</li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASYSTEM-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:SYSTEM%20%28MGL-PAX:READER%20SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:SYSTEM%20%28MGL-PAX:READER%20SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29" >SYSTEM</a></span></span> <span class="locative-args">ACTOR-CONTEXT (= NIL)</span></span></p>

<p>A reference to the <code>actor-system</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AID-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-CONTEXT-3AACTOR-CONTEXT-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ID%20%28MGL-PAX:READER%20SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ID%20%28MGL-PAX:READER%20SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%29" >ID</a></span></span> <span class="locative-args">ACTOR-CONTEXT (:ID = NIL)</span></span></p>

<p>The id of this actor-context. Usually a string.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-NAME-EXISTS-20CONDITION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-NAME-EXISTS%20CONDITION"></a></p>
<ul>
<li><span class=reference-bullet><span class=reference><span class="locative-type">[condition]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-NAME-EXISTS%20CONDITION" >ACTOR-NAME-EXISTS</a></span></span> <span class="locative-args"><a href="http://www.lispworks.com/documentation/HyperSpec/Body/e_error.htm" title="ERROR (MGL-PAX:CLHS CONDITION)">ERROR</a></span></span></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3A-40AC-PROTOCOL-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION" title="Actor-Context">&#8592;</a> <a href="#SENTO.ACTOR-CONTEXT:@ACTOR-CONTEXT%20MGL-PAX:SECTION" title="Actor-Context">&#8593;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8594;</a> <a href="#SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION" title="Actor-Context protocol">&#8634;</a></span></span></p>
<h4><a href="#SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION">2.2.1 Actor-Context protocol</a></h4>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-OF-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-OF%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20GENERIC-FUNCTION" >ACTOR-OF</a></span></span> <span class="locative-args">CONTEXT &amp;KEY RECEIVE INIT DESTROY DISPATCHER STATE TYPE NAME QUEUE-SIZE &amp;ALLOW-OTHER-KEYS</span></span></p>

<p>Interface for creating an actor.</p>

<p><strong>!!! Attention:</strong> this factory function wraps the <a href="#SENTO.ACTOR:MAKE-ACTOR%20GENERIC-FUNCTION" title="SENTO.ACTOR:MAKE-ACTOR GENERIC-FUNCTION"><code>act:make-actor</code></a> functionality to something more simple to use. 
Using this function there is no need to use both <code>act:make-actor</code>.</p>

<p><code>context</code> is either an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>, an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a>, or an <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>act:actor</code></a> (any type of actor).
The new actor is created in the given context.</p>

<ul>
<li><p><code>:receive</code> is required and must be a 1-arity function where the arguments is received message object.
The function can be just a lambda like <code>(lambda (msg) ...)</code>.</p></li>
<li><p><code>:init</code>: is an optional initialization function with one argument: the actor instance (self).
This represents a 'start' hook that is called after the actor was fully initialized.</p></li>
<li><p><code>:destroy</code>: is an optional destroy function also with the actor instance as argument.
This function allows to unsubsribe from event-stream or such.</p></li>
<li><p><code>:state</code> key can be used to initialize with a state.</p></li>
<li><p><code>:dispatcher</code> key can be used to define the message dispatcher manually.
  Options that are available by default are <code>:shared</code> (default) and <code>:pinned</code>. When you defined a custom dispatcher it can be specified here.</p></li>
<li><p><code>:type</code> can specify a custom actor class. See <code>act:make-actor</code> for more info.</p></li>
<li><p><code>:name</code> to set a specific name to the actor, otherwise a random name will be used.</p></li>
</ul>

<p>Additional options:</p>

<ul>
<li><code>:queue-size</code> limits the message-box's size. By default, it is unbounded.</li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AFIND-ACTORS-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:FIND-ACTORS%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:FIND-ACTORS%20GENERIC-FUNCTION" >FIND-ACTORS</a></span></span> <span class="locative-args">CONTEXT PATH &amp;KEY TEST KEY</span></span></p>

<p>Returns actors to be found by the criteria of:</p>

<ul>
<li><p><code>context</code>: an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>AC:ACTOR-CONTEXT</code></a>, or an <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>ACT:ACTOR</code></a> or an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>ASYS:ACTOR-SYSTEM</code></a> as all three implement <code>find-actors</code>.</p></li>
<li><p><code>path</code>: a path designator to be found. This can be just an actor name, like 'foo', then <code>find-actors</code> will only look in the given context for the actor. It can also be: 'foo/bar', a relative path, in which case <code>find-actors</code> will traverse the path (here 'bar' is a child of 'foo') to the last context and will try to find the actor by name there, 'bar' in this case. Also possible is a root path like '/user/foo/bar' which will start traversing contexts started from the root context, which is the actor-system.</p></li>
<li><p><code>test</code>: a 2-arity test function where the 1st argument is the <code>path</code>, the 2nd is the a result of the <code>key</code> function (which defaults to <a href="#SENTO.ACTOR-CELL:NAME%20%28MGL-PAX:READER%20SENTO.ACTOR-CELL:ACTOR-CELL%29" title="SENTO.ACTOR-CELL:NAME (MGL-PAX:READER SENTO.ACTOR-CELL:ACTOR-CELL)"><code>ACT-CELL:NAME</code></a>, so the name of the actor). The default function for <code>test</code> is <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stgeq_.htm" title="STRING= (MGL-PAX:CLHS FUNCTION)"><code>STRING=</code></a>. However, in case of a multi-subpath <code>path</code> both <code>test</code> and <code>key</code> only apply to the last path component, which designates the actor name to be found.</p></li>
<li><p><code>key</code>: a 1-arity function applied on an actor instance. Defaults to <code>ACT-CELL:NAME</code>.</p></li>
</ul>

<p>Depending on <code>test</code> function the last path component can be used as a wildcard when using a <code>test</code> function like <code>STR:STARTS-WITH-P</code> or <code>STR:CONTAINSP</code> for example.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AALL-ACTORS-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ALL-ACTORS%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ALL-ACTORS%20GENERIC-FUNCTION" >ALL-ACTORS</a></span></span> <span class="locative-args">CONTEXT</span></span></p>

<p>Retrieves all actors of this context as a list</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASTOP-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:STOP%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:STOP%20GENERIC-FUNCTION" >STOP</a></span></span> <span class="locative-args">CONTEXT ACTOR &amp;KEY WAIT</span></span></p>

<p>Stops the given actor on the context. 
The context may either be an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>actor-context</code></a>, or an <code>actor-system</code>.
The actor is then also removed from the context.
Specify <code>wait</code> as <code>T</code> to block until the actor is stopped (default <code>NIL</code>).</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASHUTDOWN-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CONTEXT:SHUTDOWN%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:SHUTDOWN%20GENERIC-FUNCTION" >SHUTDOWN</a></span></span> <span class="locative-args">CONTEXT &amp;KEY WAIT</span></span></p>

<p>Stops all actors in this context.
When the context is an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>actor-context</code></a> this still stop the actor context and all its actors.
For the <code>actor-system</code> it will stop the whole system with all actors.
Specify <code>wait</code> as <code>T</code> to block until all actors of the context are stopped (default <code>NIL</code>).</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3A-40ACTOR-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ACTOR-CONTEXT:@AC-PROTOCOL%20MGL-PAX:SECTION" title="Actor-Context protocol">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION" title="Actor-Cell">&#8594;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8634;</a></span></span></p>
<h3><a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION">2.3 Actor</a></h3>
<h6>[in package SENTO.ACTOR with nicknames ACT]</h6>
<p><a id="x-28SENTO-2EACTOR-3AACTOR-20CLASS-29"></a>
<a id="SENTO.ACTOR:ACTOR%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.ACTOR:ACTOR%20CLASS" >ACTOR</a></span></span> <span class="locative-args"><a href="#SENTO.ACTOR-CELL:ACTOR-CELL%20CLASS" title="SENTO.ACTOR-CELL:ACTOR-CELL CLASS">ACTOR-CELL</a></span></span></p>

<p>This is the <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>actor</code></a> class.</p>

<p>The <code>actor</code> does its message handling using the <code>receive</code> function.</p>

<p>The <code>receive</code> function takes one argument (the message). For backwards compatibility and for convenience it can still be used to provide an immediate return for <a href="#SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK-S GENERIC-FUNCTION"><code>act:ask-s</code></a>. <a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" title="SENTO.ACTOR:TELL GENERIC-FUNCTION"><code>act:tell</code></a> and <a href="#SENTO.ACTOR:ASK%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK GENERIC-FUNCTION"><code>act:ask</code></a> ignore a return value.</p>

<p>There is asynchronous <code>tell</code>, a synchronous <code>ask-s</code> and asynchronous <code>ask</code> which all can be used to send messages to the actor. <code>ask-s</code> provides a synchronous return taken from the <code>receive</code> functions return value. 'ask' provides a return wrapped in a future. But the actor has to explicitly use <code>*sender*</code> to formulate a response. <code>tell</code> is just fire and forget.</p>

<p>To stop an actors message processing in order to cleanup resouces you should <code>tell</code> (or <code>ask-s</code>) the <code>:stop</code> message. It will respond with <code>:stopped</code> (in case of <code>ask(-s)</code>).</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AMAKE-ACTOR-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:MAKE-ACTOR%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:MAKE-ACTOR%20GENERIC-FUNCTION" >MAKE-ACTOR</a></span></span> <span class="locative-args">RECEIVE &amp;KEY NAME STATE TYPE INIT DESTROY &amp;ALLOW-OTHER-KEYS</span></span></p>

<p>Constructs an <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>actor</code></a>.</p>

<p>Arguments:</p>

<ul>
<li><p><code>receive</code>: message handling function taking one argument, the message.</p></li>
<li><p><code>name</code>: give the actor a name. Must be unique within an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a>.</p></li>
<li><p><code>type</code>: Specify a custom actor class as the <code>:type</code> key. Defaults to 'actor.
Say you have a custom actor <code>custom-actor</code> and want <code>make-actor</code> create an instance of it.
Then specify <code>:type 'custom-actor</code> on <a href="#SENTO.ACTOR:MAKE-ACTOR%20GENERIC-FUNCTION" title="SENTO.ACTOR:MAKE-ACTOR GENERIC-FUNCTION"><code>make-actor</code></a> function.
If you have additional initializations to make you can do so in <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_init_i.htm" title="INITIALIZE-INSTANCE (MGL-PAX:CLHS GENERIC-FUNCTION)"><code>initialize-instance</code></a>.</p></li>
<li><p><code>state</code>: initialize an actor with a state. (default is <code>nil</code>)</p></li>
<li><p><code>init</code> and <code>destroy</code>: are functions that take one argument, the actor instance.
Those hooks are called on (after) initialization and (after) stop respectively.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3ATELL-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:TELL%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" >TELL</a></span></span> <span class="locative-args">ACTOR MESSAGE &amp;OPTIONAL SENDER</span></span></p>

<p>Sends a message to the <code>actor</code>. <code>tell</code> is asynchronous.
<code>tell</code> does not expect a result. If a <code>sender</code> is specified the receiver will be able to send a response.</p>

<p>Alternatively to the <a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" title="SENTO.ACTOR:TELL GENERIC-FUNCTION"><code>tell</code></a> function one can equally use the <code>!</code> function designator.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AASK-S-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION" >ASK-S</a></span></span> <span class="locative-args">ACTOR MESSAGE &amp;KEY TIME-OUT</span></span></p>

<p>Sends a message to the <code>actor</code>. <code>ask-s</code> is synchronous and waits for a result.
Specify <code>timeout</code> if a message is to be expected after a certain time.
An <code>:handler-error</code> with <code>timeout</code> condition will be returned if the call timed out.</p>

<p><code>ask-s</code> assumes, no matter if <code>ask-s</code> is issued from outside or inside an actor, that the response is delivered back to the caller. That's why <code>ask-s</code> does block the execution until the result is available. The <code>receive</code> function return value will be used as the result of <code>receive</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AASK-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:ASK%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:ASK%20GENERIC-FUNCTION" >ASK</a></span></span> <span class="locative-args">ACTOR MESSAGE &amp;KEY TIME-OUT</span></span></p>

<p>Sends a message to the <code>actor</code>. A <code>future</code> is returned.
Specify <code>timeout</code> if a message is to be expected after a certain time.
An <code>:handler-error</code> with <code>timeout</code> condition will be returned is the call timed out.</p>

<p>An <code>ask</code> is similar to a <a href="#SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK-S GENERIC-FUNCTION"><code>ask-s</code></a> in that the caller gets back a result 
but it doesn't have to actively wait for it. Instead a <code>future</code> wraps the result.
However, the internal message handling is based on <a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" title="SENTO.ACTOR:TELL GENERIC-FUNCTION"><code>tell</code></a>.
How this works is that the message to the target <code>actor</code> is not 'sent' using the callers thread but instead an anonymous <code>actor</code> is started behind the scenes. This anonymous actor can weit for a response from the target actor. The response then fulfills the future.</p>

<p>Alternatively to the <a href="#SENTO.ACTOR:ASK%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK GENERIC-FUNCTION"><code>ask</code></a> function one can equally use the <code>?</code> function designator.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AREPLY-20FUNCTION-29"></a>
<a id="SENTO.ACTOR:REPLY%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:REPLY%20FUNCTION" >REPLY</a></span></span> <span class="locative-args">MSG &amp;OPTIONAL (SENDER <code>*SENDER*</code>)</span></span></p>

<p>Replies to a sender. Sender must exist.
Use this from within receive function to reply to a sender.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3ABECOME-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:BECOME%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:BECOME%20GENERIC-FUNCTION" >BECOME</a></span></span> <span class="locative-args">NEW-BEHAVIOR</span></span></p>

<p>Changes the receive of the actor to the given <code>new-behavior</code> function.
The <code>new-behavior</code> function must accept 3 parameters: the actor instance, the message and the current state.
This function should be called from within the behavior receive function.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AUNBECOME-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:UNBECOME%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:UNBECOME%20GENERIC-FUNCTION" >UNBECOME</a></span></span></span></p>

<p>Reverts any behavior applied via <a href="#SENTO.ACTOR:BECOME%20GENERIC-FUNCTION" title="SENTO.ACTOR:BECOME GENERIC-FUNCTION"><code>become</code></a> back to the default <code>receive</code> function.
This function should be called from within the behavior receive function.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3ACONTEXT-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:CONTEXT%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:CONTEXT%20GENERIC-FUNCTION" >CONTEXT</a></span></span> <span class="locative-args">ACTOR</span></span></p>

<p>This is the <code>actor-context</code> every actor is composed of.
When the actor is created from scratch it has no <code>actor-context</code>.
When created through the <code>actor-context</code>s, or system's <code>actor-of</code> function an <code>actor-context</code> will be set.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3APATH-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:PATH%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:PATH%20GENERIC-FUNCTION" >PATH</a></span></span> <span class="locative-args">ACTOR</span></span></p>

<p>The path of the actor, including the actor itself.
The path denotes a tree which starts at the system context.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AWATCH-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:WATCH%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:WATCH%20GENERIC-FUNCTION" >WATCH</a></span></span> <span class="locative-args">ACTOR WATCHER</span></span></p>

<p>Registers <code>watcher</code> as a watcher of <code>actor</code>.
Watching lets the watcher know about lifecycle changes of the actor being watched.
I.e.: when it stopped. The message being sent in this case is: <code>(cons :stopped actor-instance)</code></p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AUNWATCH-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:UNWATCH%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:UNWATCH%20GENERIC-FUNCTION" >UNWATCH</a></span></span> <span class="locative-args">ACTOR WATCHER</span></span></p>

<p>Unregisters <code>watcher</code> of <code>actor</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AWATCHERS-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:WATCHERS%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:WATCHERS%20GENERIC-FUNCTION" >WATCHERS</a></span></span> <span class="locative-args">ACTOR</span></span></p>

<p>Returns a list of watchers of <code>actor</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3APRE-START-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:PRE-START%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:PRE-START%20GENERIC-FUNCTION" >PRE-START</a></span></span> <span class="locative-args">ACTOR</span></span></p>

<p>Generic function definition called after initialization but before messages are accepted.
An <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> is available at this point as well as <code>act:*state*</code> variable definition.</p>

<p>Under normal circumstances one would provide an <code>init</code> function at construction of the actor instead (see above).
This generic function is more meant to create specialized actors by providing different implementations.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AAFTER-STOP-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR:AFTER-STOP%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR:AFTER-STOP%20GENERIC-FUNCTION" >AFTER-STOP</a></span></span> <span class="locative-args">ACTOR</span></span></p>

<p>Generic function definition that is called after the actor has stopped, that is after the message box is stopped.
No more messages are being processed.</p>

<p>Under normal circumstances one would provide an <code>destroy</code> function at construction of the actor instead (see above).
This generic function is more meant to create specialized actors by providing different implementations.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3ASUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29" >SENTO.EVENTSTREAM:SUBSCRIBE</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) (SUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to subscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AUNSUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29" >SENTO.EVENTSTREAM:UNSUBSCRIBE</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) (UNSUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to unsubscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3APUBLISH-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20T-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29" >SENTO.EVENTSTREAM:PUBLISH</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) MESSAGE</span></span></p>

<p>Convenience. Allows to publish to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AFIND-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20T-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:FIND-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29" >SENTO.ACTOR-CONTEXT:FIND-ACTORS</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>ACTOR</code></a>) PATH</span></span></p>

<p><a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol implementation.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AALL-ACTORS-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ALL-ACTORS%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29" >SENTO.ACTOR-CONTEXT:ALL-ACTORS</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>ACTOR</code></a>)</span></span></p>

<p><a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol implementation.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3AACTOR-OF-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29" >SENTO.ACTOR-CONTEXT:ACTOR-OF</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>ACTOR</code></a>)</span></span></p>

<p><a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol implementation</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CONTEXT-3ASYSTEM-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.ACTOR-CONTEXT:SYSTEM%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CONTEXT:SYSTEM%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%29%29" >SENTO.ACTOR-CONTEXT:SYSTEM</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>ACTOR</code></a>)</span></span></p>

<p>Retrieves the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> from actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3A-40ACTOR-CELL-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8592;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8593;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION" title="Message-box base class">&#8594;</a> <a href="#SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION" title="Actor-Cell">&#8634;</a></span></span></p>
<h4><a href="#SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION">2.3.1 Actor-Cell</a></h4>
<h6>[in package SENTO.ACTOR-CELL with nicknames ACT-CELL]</h6>
<p><a id="x-28SENTO-2EACTOR-CELL-3AACTOR-CELL-20CLASS-29"></a>
<a id="SENTO.ACTOR-CELL:ACTOR-CELL%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:ACTOR-CELL%20CLASS" >ACTOR-CELL</a></span></span></span></p>

<p><code>actor-cell</code> is the base of the <code>actor</code>.
It encapsulates state and can executes async operations.
State can be changed by <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm" title="SETF (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>setf</code></a>ing <code>*state*</code> special variable from inside <code>receive</code> function, via calling <a href="#SENTO.ACTOR-CELL:CALL%20FUNCTION" title="SENTO.ACTOR-CELL:CALL FUNCTION"><code>call</code></a> or <a href="#SENTO.ACTOR-CELL:CAST%20FUNCTION" title="SENTO.ACTOR-CELL:CAST FUNCTION"><code>cast</code></a>.
Where <code>call</code> is waiting for a result and <code>cast</code> does not.
For each <code>call</code> and <code>cast</code> handlers must be implemented by subclasses.</p>

<p>It uses a <code>message-box</code> to processes the received messages.
When the <code>actor</code>/<code>actor-cell</code> was created ad-hoc (out of the <code>actor-system</code>/<code>actor-context</code>),
it will not have a message-box and can't process messages.
When the <code>actor</code> is created through the <code>actor-system</code> or <code>actor-context</code>,
one can decide what kind of message-box/dispatcher should be used for the new <code>actor</code>.</p>

<p>See <code>actor-context</code> <code>actor-of</code> method for more information on this.</p>

<p>To stop an <code>actor</code> message handling and you can send the <code>:stop</code> message
either via <code>call</code> (which will respond with <code>:stopped</code>) or <code>cast</code>.
This is to cleanup thread resources when the actor is not needed anymore.</p>

<p>Note: the <code>actor-cell</code> uses <code>call</code> and <code>cast</code> functions which translate to <code>ask-s</code> and <code>tell</code> on the <code>actor</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ANAME-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-CELL-3AACTOR-CELL-29-29"></a>
<a id="SENTO.ACTOR-CELL:NAME%20%28MGL-PAX:READER%20SENTO.ACTOR-CELL:ACTOR-CELL%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:NAME%20%28MGL-PAX:READER%20SENTO.ACTOR-CELL:ACTOR-CELL%29" >NAME</a></span></span> <span class="locative-args">ACTOR-CELL (:NAME = (STRING (GENSYM &quot;actor-&quot;)))</span></span></p>

<p>The name of the actor/actor-cell. If no name is specified a default one is applied.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ASTATE-20-28MGL-PAX-3AREADER-20SENTO-2EACTOR-CELL-3AACTOR-CELL-29-29"></a>
<a id="SENTO.ACTOR-CELL:STATE%20%28MGL-PAX:READER%20SENTO.ACTOR-CELL:ACTOR-CELL%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:STATE%20%28MGL-PAX:READER%20SENTO.ACTOR-CELL:ACTOR-CELL%29" >STATE</a></span></span> <span class="locative-args">ACTOR-CELL (:STATE = NIL)</span></span></p>

<p>The encapsulated state.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3AMSGBOX-20-28MGL-PAX-3AACCESSOR-20SENTO-2EACTOR-CELL-3AACTOR-CELL-29-29"></a>
<a id="SENTO.ACTOR-CELL:MSGBOX%20%28MGL-PAX:ACCESSOR%20SENTO.ACTOR-CELL:ACTOR-CELL%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[accessor]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:MSGBOX%20%28MGL-PAX:ACCESSOR%20SENTO.ACTOR-CELL:ACTOR-CELL%29" >MSGBOX</a></span></span> <span class="locative-args">ACTOR-CELL (= NIL)</span></span></p>

<p>The <code>message-box</code>. By default the <code>actor</code>/<a href="#SENTO.ACTOR-CELL:ACTOR-CELL%20CLASS" title="SENTO.ACTOR-CELL:ACTOR-CELL CLASS"><code>actor-cell</code></a> has no message-box.
When the actor is created through the <code>actor-context</code> of an actor, or the <code>actor-system</code>
then it will be populated with a message-box.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3AHANDLE-CALL-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:HANDLE-CALL%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:HANDLE-CALL%20GENERIC-FUNCTION" >HANDLE-CALL</a></span></span> <span class="locative-args">ACTOR-CELL MESSAGE</span></span></p>

<p>Handles calls to the server. Must be implemented by subclasses.
The result of the last expression of this function is returned back to the 'caller'.
State of the cell can be changed via <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm" title="SETF (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>setf</code></a>ing <code>*state*</code> variable.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3AHANDLE-CAST-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:HANDLE-CAST%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:HANDLE-CAST%20GENERIC-FUNCTION" >HANDLE-CAST</a></span></span> <span class="locative-args">ACTOR-CELL MESSAGE</span></span></p>

<p>Handles casts to the server. Must be implemented by subclasses.
State of the cell can be changed via <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm" title="SETF (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>setf</code></a>ing <code>*state*</code> variable.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ASTOP-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:STOP%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:STOP%20GENERIC-FUNCTION" >STOP</a></span></span> <span class="locative-args">ACTOR-CELL &amp;OPTIONAL WAIT</span></span></p>

<p>Stops the actor-cells message processing gracefully.
This is not an immediate stop.
There are two ways to stop an actor (cell).</p>

<ol>
<li><p>by calling this function.
It is not an immediate stop. The actor will finish the current message processing.
<code>wait</code>: waits until the cell is stopped.</p></li>
<li><p>by sending <code>:stop</code> to the actor (cell).
This won't allow to wait when the actor is stopped, even not with <code>ask-s</code>.
The <code>:stop</code> message (symbol) is normally processed by the actors message processing.</p></li>
</ol></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ACALL-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:CALL%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:CALL%20FUNCTION" >CALL</a></span></span> <span class="locative-args">ACTOR-CELL MESSAGE &amp;KEY (TIME-OUT <code>NIL</code>)</span></span></p>

<p>Send a message to a actor-cell instance and wait for a result.
Specify a timeout in seconds if you require a result within a certain period of time.
Be aware though that this is a resource intensive wait based on a waiting thread.
The result can be of different types.
Normal result: the last expression of <a href="#SENTO.ACTOR-CELL:HANDLE-CALL%20GENERIC-FUNCTION" title="SENTO.ACTOR-CELL:HANDLE-CALL GENERIC-FUNCTION"><code>handle-call</code></a> (or <code>receive</code> in <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>act:actor</code></a>) implementation.
Error result: `(cons :handler-error <condition>)'
In case of time-out the error condition is a bt2:timeout.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ACAST-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:CAST%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:CAST%20FUNCTION" >CAST</a></span></span> <span class="locative-args">ACTOR-CELL MESSAGE &amp;OPTIONAL SENDER</span></span></p>

<p>Sends a message to a actor-cell asynchronously. There is no result.
If a `sender' is specified the result will be sent to the sender.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-CELL-3ARUNNING-P-20FUNCTION-29"></a>
<a id="SENTO.ACTOR-CELL:RUNNING-P%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ACTOR-CELL:RUNNING-P%20FUNCTION" >RUNNING-P</a></span></span> <span class="locative-args">ACTOR-CELL</span></span></p>

<p>Returns true if this server is running. <code>nil</code> otherwise.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3A-40MESSAGE-BOX-BASE-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ACTOR-CELL:@ACTOR-CELL%20MGL-PAX:SECTION" title="Actor-Cell">&#8592;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8593;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION" title="Message-box threaded">&#8594;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION" title="Message-box base class">&#8634;</a></span></span></p>
<h4><a href="#SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION">2.3.2 Message-box base class</a></h4>
<h6>[in package SENTO.MESSAGEB with nicknames MESGB]</h6>
<p><a id="x-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-BASE-20CLASS-29"></a>
<a id="SENTO.MESSAGEB:MESSAGE-BOX-BASE%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:MESSAGE-BOX-BASE%20CLASS" >MESSAGE-BOX-BASE</a></span></span></span></p>

<p>The user does not need to create a message-box manually. It is automatically created and added to the <code>actor</code> when the actor is created through <a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20GENERIC-FUNCTION" title="SENTO.ACTOR-CONTEXT:ACTOR-OF GENERIC-FUNCTION"><code>ac:actor-of</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ANAME-20-28MGL-PAX-3AREADER-20SENTO-2EMESSAGEB-3AMESSAGE-BOX-BASE-29-29"></a>
<a id="SENTO.MESSAGEB:NAME%20%28MGL-PAX:READER%20SENTO.MESSAGEB:MESSAGE-BOX-BASE%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:NAME%20%28MGL-PAX:READER%20SENTO.MESSAGEB:MESSAGE-BOX-BASE%29" >NAME</a></span></span> <span class="locative-args">MESSAGE-BOX-BASE (:NAME = (STRING (GENSYM &quot;mesgb-&quot;)))</span></span></p>

<p>The name of the message-box.
The default name is concatenated of &quot;mesgb-&quot; and a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_gensym.htm" title="GENSYM (MGL-PAX:CLHS FUNCTION)"><code>gensym</code></a> generated random number.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3AMAX-QUEUE-SIZE-20-28MGL-PAX-3AREADER-20SENTO-2EMESSAGEB-3AMESSAGE-BOX-BASE-29-29"></a>
<a id="SENTO.MESSAGEB:MAX-QUEUE-SIZE%20%28MGL-PAX:READER%20SENTO.MESSAGEB:MESSAGE-BOX-BASE%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:MAX-QUEUE-SIZE%20%28MGL-PAX:READER%20SENTO.MESSAGEB:MESSAGE-BOX-BASE%29" >MAX-QUEUE-SIZE</a></span></span> <span class="locative-args">MESSAGE-BOX-BASE (:MAX-QUEUE-SIZE = 0)</span></span></p>

<p>0 or nil will make an unbounded queue.
A value <code>&gt; 0</code> will make a bounded queue.
Don't make it too small. A queue size of 1000 might be a good choice.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ASUBMIT-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.MESSAGEB:SUBMIT%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:SUBMIT%20GENERIC-FUNCTION" >SUBMIT</a></span></span> <span class="locative-args">MESSAGE-BOX-BASE MESSAGE WITHREPLY-P TIME-OUT HANDLER-FUN-ARGS</span></span></p>

<p>Submit a message to the mailbox to be queued and handled.
<code>handler-fun-args</code>: list with first element the function designator and rest arguments.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ASTOP-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.MESSAGEB:STOP%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:STOP%20GENERIC-FUNCTION" >STOP</a></span></span> <span class="locative-args">MESSAGE-BOX-BASE &amp;OPTIONAL WAIT</span></span></p>

<p>Stops the message processing.
The message processing is not terminated while a message is still processed.
Rather it is a graceful stop by waiting until a message has been processed.
Provide <code>wait</code> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>EQ</code></a> <code>T</code> to wait until the actor cell is stopped.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ASTOP-20-28METHOD-20NIL-20-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-BASE-29-29-29"></a>
<a id="SENTO.MESSAGEB:STOP%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX-BASE%29%29"></a></p>
<ul>
<li><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:STOP%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX-BASE%29%29" >STOP</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.MESSAGEB:MESSAGE-BOX-BASE%20CLASS" title="SENTO.MESSAGEB:MESSAGE-BOX-BASE CLASS"><code>MESSAGE-BOX-BASE</code></a>)</span></span></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3A-40MESSAGE-BOX-2FBT-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX-BASE%20MGL-PAX:SECTION" title="Message-box base class">&#8592;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8593;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION" title="Message-box dispatched">&#8594;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION" title="Message-box threaded">&#8634;</a></span></span></p>
<h4><a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION">2.3.3 Message-box threaded</a></h4>
<h6>[in package SENTO.MESSAGEB with nicknames MESGB]</h6>
<p><a id="x-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-2FBT-20CLASS-29"></a>
<a id="SENTO.MESSAGEB:MESSAGE-BOX%2FBT%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:MESSAGE-BOX%2FBT%20CLASS" >MESSAGE-BOX/BT</a></span></span> <span class="locative-args"><a href="#SENTO.MESSAGEB:MESSAGE-BOX-BASE%20CLASS" title="SENTO.MESSAGEB:MESSAGE-BOX-BASE CLASS">MESSAGE-BOX-BASE</a></span></span></p>

<p>Bordeaux-Threads based message-box with a single thread operating on a message queue.
This is used when the actor is created using a <code>:pinned</code> dispatcher type.
There is a limit on the maximum number of actors/agents that can be created with
this kind of queue because each message-box (and with that each actor) requires exactly one thread.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ASUBMIT-20-28METHOD-20NIL-20-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-2FBT-20T-20T-20T-20T-29-29-29"></a>
<a id="SENTO.MESSAGEB:SUBMIT%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX%2FBT%20T%20T%20T%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:SUBMIT%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX%2FBT%20T%20T%20T%20T%29%29" >SUBMIT</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.MESSAGEB:MESSAGE-BOX%2FBT%20CLASS" title="SENTO.MESSAGEB:MESSAGE-BOX/BT CLASS"><code>MESSAGE-BOX/BT</code></a>) MESSAGE WITHREPLY-P TIME-OUT HANDLER-FUN-ARGS</span></span></p>

<p>The <code>handler-fun-args</code> argument must contain a handler function as first list item.
It will be apply'ed with the rest of the args when the message was 'popped' from queue.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3A-40MESSAGE-BOX-2FDP-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FBT%20MGL-PAX:SECTION" title="Message-box threaded">&#8592;</a> <a href="#SENTO.ACTOR:@ACTOR%20MGL-PAX:SECTION" title="Actor">&#8593;</a> <a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">&#8594;</a> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION" title="Message-box dispatched">&#8634;</a></span></span></p>
<h4><a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION">2.3.4 Message-box dispatched</a></h4>
<h6>[in package SENTO.MESSAGEB with nicknames MESGB]</h6>
<p><a id="x-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-2FDP-20CLASS-29"></a>
<a id="SENTO.MESSAGEB:MESSAGE-BOX%2FDP%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:MESSAGE-BOX%2FDP%20CLASS" >MESSAGE-BOX/DP</a></span></span> <span class="locative-args"><a href="#SENTO.MESSAGEB:MESSAGE-BOX-BASE%20CLASS" title="SENTO.MESSAGEB:MESSAGE-BOX-BASE CLASS">MESSAGE-BOX-BASE</a></span></span></p>

<p>This message box is a message-box that uses the <code>system</code>s <code>dispatcher</code>.
This has the advantage that an almost unlimited actors/agents can be created.
This message-box doesn't 'own' a thread. It uses the <code>dispatcher</code> to handle the message processing.
The <code>dispatcher</code> is kind of like a thread pool.</p></li>
</ul>
<p><a id="x-28SENTO-2EMESSAGEB-3ASUBMIT-20-28METHOD-20NIL-20-28SENTO-2EMESSAGEB-3AMESSAGE-BOX-2FDP-20T-20T-20T-20T-29-29-29"></a>
<a id="SENTO.MESSAGEB:SUBMIT%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX%2FDP%20T%20T%20T%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.MESSAGEB:SUBMIT%20%28METHOD%20NIL%20%28SENTO.MESSAGEB:MESSAGE-BOX%2FDP%20T%20T%20T%20T%29%29" >SUBMIT</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.MESSAGEB:MESSAGE-BOX%2FDP%20CLASS" title="SENTO.MESSAGEB:MESSAGE-BOX/DP CLASS"><code>MESSAGE-BOX/DP</code></a>) MESSAGE WITHREPLY-P TIME-OUT HANDLER-FUN-ARGS</span></span></p>

<p>Submitting a message on a multi-threaded <code>dispatcher</code> is different as submitting on a single threaded message-box. On a single threaded message-box the order of message processing is guaranteed even when submitting from multiple threads. On the <code>dispatcher</code> this is not the case. The order cannot be guaranteed when messages are processed by different <code>dispatcher</code> threads. However, we still guarantee a 'single-threadedness' regarding the state of the actor. This is achieved here by protecting the <code>handler-fun-args</code> execution with a lock.</p>

<p>The <code>time-out</code> with the 'dispatcher mailbox' assumes that the message received the dispatcher queue
and the handler in a reasonable amount of time, so that the effective time-out applies on the actual
handling of the message on the dispatcher queue thread.</p>

<p>Returns the handler-result if <code>withreply-p' is eq to``T</code>', otherwise the return is just `<code>T</code>' and is usually ignored.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3A-40AGENT-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.AGENT:@AGENT%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.MESSAGEB:@MESSAGE-BOX%2FDP%20MGL-PAX:SECTION" title="Message-box dispatched">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION" title="Hash-table agent">&#8594;</a> <a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">&#8634;</a></span></span></p>
<h3><a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION">2.4 Agent</a></h3>
<h6>[in package SENTO.AGENT with nicknames AGT]</h6>
<p><a id="x-28SENTO-2EAGENT-3AAGENT-20CLASS-29"></a>
<a id="SENTO.AGENT:AGENT%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.AGENT:AGENT%20CLASS" >AGENT</a></span></span> <span class="locative-args"><a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS">ACTOR</a></span></span></p>

<p>Specialized <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>actor</code></a> class called <code>agent</code>.
It is meant primarily to encapsulate state.
To access state it provides <a href="#SENTO.AGENT:AGENT-GET%20FUNCTION" title="SENTO.AGENT:AGENT-GET FUNCTION"><code>agent-get</code></a> and <a href="#SENTO.AGENT:AGENT-UPDATE%20FUNCTION" title="SENTO.AGENT:AGENT-UPDATE FUNCTION"><code>agent-update</code></a> to update state.
Stop an agent with <a href="#SENTO.AGENT:AGENT-STOP%20FUNCTION" title="SENTO.AGENT:AGENT-STOP FUNCTION"><code>agent-stop</code></a> to free resources (threads).</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3AMAKE-AGENT-20FUNCTION-29"></a>
<a id="SENTO.AGENT:MAKE-AGENT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT:MAKE-AGENT%20FUNCTION" >MAKE-AGENT</a></span></span> <span class="locative-args">STATE-FUN &amp;OPTIONAL ACTOR-CONTEXT (DISPATCHER-ID <code>:SHARED</code>)</span></span></p>

<p>Makes a new <a href="#SENTO.AGENT:AGENT%20CLASS" title="SENTO.AGENT:AGENT CLASS"><code>agent</code></a> instance.</p>

<ul>
<li><p><code>state-fun</code> is a function that takes no parameter and provides the initial state of the <code>agent</code> as return value.</p></li>
<li><p><code>actor-context</code>: optionally specify an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> as <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a>. If specified the agent will be registered in the system and destroyed with it should the <code>asys:actor-system</code> be destroyed. In addition the agent will use the systems shared message dispatcher and will <em>not</em> create it's own.</p></li>
<li><p><code>dispatcher-id</code>: the dispatcher is configurable. Default is <code>:shared</code>. But you may use also <code>:pinned</code> or a custom configured one. Be aware that <code>:shared</code> of a custom dispatcher only works if an <code>actor-context</code> was specified.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3AAGENT-GET-20FUNCTION-29"></a>
<a id="SENTO.AGENT:AGENT-GET%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT:AGENT-GET%20FUNCTION" >AGENT-GET</a></span></span> <span class="locative-args">AGENT GET-FUN</span></span></p>

<p>Gets the current state of the <code>agent</code>.
<code>get-fun</code> must accept one parameter. That is the current-state of the <code>agent</code>.
To return the current state <code>get-fun</code> may be just the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_identi.htm" title="IDENTITY (MGL-PAX:CLHS FUNCTION)"><code>identity</code></a> function.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3AAGENT-UPDATE-20FUNCTION-29"></a>
<a id="SENTO.AGENT:AGENT-UPDATE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT:AGENT-UPDATE%20FUNCTION" >AGENT-UPDATE</a></span></span> <span class="locative-args">AGENT UPDATE-FUN</span></span></p>

<p>Updates the <code>agent</code> state.</p>

<p><code>update-fun</code> must accept one parameter. That is the current state of the <code>agent</code>. The return value of <code>update-fun</code> will be taken as the new state of the <code>agent</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3AAGENT-UPDATE-AND-GET-20FUNCTION-29"></a>
<a id="SENTO.AGENT:AGENT-UPDATE-AND-GET%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT:AGENT-UPDATE-AND-GET%20FUNCTION" >AGENT-UPDATE-AND-GET</a></span></span> <span class="locative-args">AGENT UPDATE-FUN</span></span></p>

<p>Updates the <code>agent</code> state.</p>

<p><code>update-fun</code> must accept one parameter. That is the current state of the <code>agent</code>. The return value of <code>update-fun</code> will be taken as the new state of the <code>agent</code>.
This function makes the update and returns the new value.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-3AAGENT-STOP-20FUNCTION-29"></a>
<a id="SENTO.AGENT:AGENT-STOP%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT:AGENT-STOP%20FUNCTION" >AGENT-STOP</a></span></span> <span class="locative-args">AGENT</span></span></p>

<p>Stops the message handling of the agent.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3A-40HASH-AGENT-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">&#8592;</a> <a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">&#8593;</a> <a href="#SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION" title="Array/Vector agent">&#8594;</a> <a href="#SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION" title="Hash-table agent">&#8634;</a></span></span></p>
<h4><a href="#SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION">2.4.1 Hash-table agent</a></h4>
<h6>[in package SENTO.AGENT.HASH with nicknames AGTHASH]</h6>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3AMAKE-HASH-AGENT-20FUNCTION-29"></a>
<a id="SENTO.AGENT.HASH:MAKE-HASH-AGENT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.HASH:MAKE-HASH-AGENT%20FUNCTION" >MAKE-HASH-AGENT</a></span></span> <span class="locative-args">CONTEXT &amp;KEY INITIAL-HASH-TABLE (ERROR-FUN <code>NIL</code>) (DISPATCHER-ID <code>:SHARED</code>)</span></span></p>

<p>Creates an agent that wraps a CL hash-table.</p>

<ul>
<li><p><code>context</code>: something implementing <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol like <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>. Specifying <code>nil</code> here creates an agent outside of an actor system. The user has to take care of that himself.</p></li>
<li><p><code>initial-hash-table</code>: specify an initial hash-table.</p></li>
<li><p><code>error-fun</code>: a 1-arrity function taking a condition that was raised.
Use this to get notified of error when using the update functions of the agent.</p></li>
<li><p><code>dispatcher-id</code>: a dispatcher. defaults to <code>:shared</code>.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3AAGENT-GETHASH-20FUNCTION-29"></a>
<a id="SENTO.AGENT.HASH:AGENT-GETHASH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.HASH:AGENT-GETHASH%20FUNCTION" >AGENT-GETHASH</a></span></span> <span class="locative-args">KEY HASH-AGENT</span></span></p>

<p>Retrieves value from hash-table, or <code>nil</code> if it doesn't exist.
See <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_gethas.htm" title="GETHASH (MGL-PAX:CLHS FUNCTION)"><code>cl:gethash</code></a> for more info.</p>

<p>This supports setting a hash using <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm" title="SETF (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>setf</code></a> in the same way as with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_hash_t.htm" title="HASH-TABLE (MGL-PAX:CLHS CLASS)"><code>cl:hash-table</code></a>.</p>

<p>Returns any raised condition or the value from <code>gethash</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3AAGENT-REMHASH-20FUNCTION-29"></a>
<a id="SENTO.AGENT.HASH:AGENT-REMHASH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.HASH:AGENT-REMHASH%20FUNCTION" >AGENT-REMHASH</a></span></span> <span class="locative-args">KEY HASH-AGENT</span></span></p>

<p>Delete a hash-table entry. See <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_remhas.htm" title="REMHASH (MGL-PAX:CLHS FUNCTION)"><code>cl:remhash</code></a>.
Returns <code>T</code> if entry existed, <code>NIL</code> otherwise.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3AAGENT-CLRHASH-20FUNCTION-29"></a>
<a id="SENTO.AGENT.HASH:AGENT-CLRHASH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.HASH:AGENT-CLRHASH%20FUNCTION" >AGENT-CLRHASH</a></span></span> <span class="locative-args">HASH-AGENT</span></span></p>

<p>Clears the hash-table. See <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_clrhas.htm" title="CLRHASH (MGL-PAX:CLHS FUNCTION)"><code>cl:clrhash</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EHASH-3AAGENT-DOHASH-20FUNCTION-29"></a>
<a id="SENTO.AGENT.HASH:AGENT-DOHASH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.HASH:AGENT-DOHASH%20FUNCTION" >AGENT-DOHASH</a></span></span> <span class="locative-args">FUN HASH-AGENT</span></span></p>

<p>'Do' arbitrary atomic operation on the hash-table.</p>

<ul>
<li><p><code>fun</code>: is a 1-arity function taking the hash-table. This function can operate on the hash-table without interference from other threads. The result of this function must be a hash-table.</p></li>
<li><p><code>hash-agent</code>: is the <code>hash-agent</code> instance.</p></li>
</ul>

<p>The result of <code>agent-dohash</code> is <code>T</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3A-40ARRAY-AGENT-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.AGENT.HASH:@HASH-AGENT%20MGL-PAX:SECTION" title="Hash-table agent">&#8592;</a> <a href="#SENTO.AGENT:@AGENT%20MGL-PAX:SECTION" title="Agent">&#8593;</a> <a href="#SENTO.FSM:@FSM%20MGL-PAX:SECTION" title="Finite state machine">&#8594;</a> <a href="#SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION" title="Array/Vector agent">&#8634;</a></span></span></p>
<h4><a href="#SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION">2.4.2 Array/Vector agent</a></h4>
<h6>[in package SENTO.AGENT.ARRAY with nicknames AGTARRAY]</h6>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AMAKE-ARRAY-AGENT-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:MAKE-ARRAY-AGENT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:MAKE-ARRAY-AGENT%20FUNCTION" >MAKE-ARRAY-AGENT</a></span></span> <span class="locative-args">CONTEXT &amp;KEY INITIAL-ARRAY (ERROR-FUN <code>NIL</code>) (DISPATCHER-ID <code>:SHARED</code>)</span></span></p>

<p>Creates an agent that wraps a CL array/vector.</p>

<ul>
<li><p><code>context</code>: something implementing <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> protocol like <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>. Specifying <code>nil</code> here creates an agent outside of an actor system. The user has to take care of that himself.</p></li>
<li><p><code>initial-array</code>: specify an initial array/vector.</p></li>
<li><p><code>error-fun</code>: a 1-arrity function taking a condition that was raised.
Use this to get notified of error when using the update functions of the agent.</p></li>
<li><p><code>dispatcher-id</code>: a dispatcher. defaults to <code>:shared</code>.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-ELT-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-ELT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-ELT%20FUNCTION" >AGENT-ELT</a></span></span> <span class="locative-args">INDEX ARRAY-AGENT</span></span></p>

<p>Retrieves the value of the specified index of the array. <code>agent-elt</code> allows <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm" title="SETF (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>setf</code></a>ing like:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">setf <span class="paren2">(<span class="code">agent-elt 0 cut</span>)</span> 11</span>)</span></span></code></pre>

<ul>
<li><p><code>index</code>: the index to retrieve.</p></li>
<li><p><code>array-agent</code>: the array agent instance.</p></li>
</ul>

<p>In case of error <code>agent-elt</code> returns the error condition that <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_elt.htm" title="ELT (MGL-PAX:CLHS FUNCTION)"><code>elt</code></a> raises.</p>

<p>The <code>setf</code> functionality will call <code>err-fun</code> on error if it has been configured.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-PUSH-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-PUSH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-PUSH%20FUNCTION" >AGENT-PUSH</a></span></span> <span class="locative-args">ITEM ARRAY-AGENT</span></span></p>

<p>Pushes a value to the array/vector. Internally uses <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_vec_ps.htm" title="VECTOR-PUSH-EXTEND (MGL-PAX:CLHS FUNCTION)"><code>vector-push-extend</code></a>, so the array must have a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fill_p.htm" title="FILL-POINTER (MGL-PAX:CLHS FUNCTION)"><code>fill-pointer</code></a>.</p>

<p><code>item</code>: item to push.<br/>
<code>array-agent</code>: the array agent instance.</p>

<p>On error it will call <code>err-fun</code> with the raised condition, if <code>err-fun</code> has been configured.</p></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-PUSH-AND-GETIDX-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-PUSH-AND-GETIDX%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-PUSH-AND-GETIDX%20FUNCTION" >AGENT-PUSH-AND-GETIDX</a></span></span> <span class="locative-args">ITEM ARRAY-AGENT</span></span></p>

<p>Pushes <code>item</code> to the array. This function is similar to <a href="#SENTO.AGENT.ARRAY:AGENT-PUSH%20FUNCTION" title="SENTO.AGENT.ARRAY:AGENT-PUSH FUNCTION"><code>agent-push</code></a> but returns the index of the pushed value similar as <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_vec_ps.htm" title="VECTOR-PUSH (MGL-PAX:CLHS FUNCTION)"><code>vector-push</code></a> does. Therefore it is based on the somewhat slower <code>ask-s</code> actor pattern. So if you don't care about the new index of the pushed item use <code>agent-push</code> instead. But this one is able to immediately return error conditions that may occur on <code>vector-push</code>.</p>

<ul>
<li><p><code>item</code>: item to push.</p></li>
<li><p><code>array-agent</code>: the array agent instance.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-POP-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-POP%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-POP%20FUNCTION" >AGENT-POP</a></span></span> <span class="locative-args">ARRAY-AGENT</span></span></p>

<p>Pops from array and returns the popped value. Internally uses <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_vec_po.htm" title="VECTOR-POP (MGL-PAX:CLHS FUNCTION)"><code>vector-pop</code></a>, so the array must have a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fill_p.htm" title="FILL-POINTER (MGL-PAX:CLHS FUNCTION)"><code>fill-pointer</code></a>. In case of error from using <code>vector-pop</code> the condition is returned.</p>

<ul>
<li><code>array-agent</code>: the array agent instance.</li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-DELETE-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-DELETE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-DELETE%20FUNCTION" >AGENT-DELETE</a></span></span> <span class="locative-args">ITEM ARRAY-AGENT &amp;REST DELETE-ARGS</span></span></p>

<p>Deletes item from array. Internally uses <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rm_rm.htm" title="DELETE (MGL-PAX:CLHS FUNCTION)"><code>delete</code></a>. Returns <code>T</code>.</p>

<ul>
<li><p><code>item</code>: the item to delete.</p></li>
<li><p><code>array-agent</code>: the array agent instance.</p></li>
<li><p><code>delete-args</code>: any arguments passed on to <code>delete</code>.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EAGENT-2EARRAY-3AAGENT-DOARRAY-20FUNCTION-29"></a>
<a id="SENTO.AGENT.ARRAY:AGENT-DOARRAY%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.AGENT.ARRAY:AGENT-DOARRAY%20FUNCTION" >AGENT-DOARRAY</a></span></span> <span class="locative-args">FUN ARRAY-AGENT</span></span></p>

<p>'Do' arbitrary atomic operation on the array.</p>

<ul>
<li><p><code>fun</code>: is a 1-arity function taking the array. This function can operate on the array without interference from other threads. The result of this function must be an array which will be the new agent state.</p></li>
<li><p><code>array-agent</code>: is the <code>array-agent</code> instance.</p></li>
</ul>

<p>The result of <code>agent-doarray</code> is <code>T</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3A-40FSM-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.FSM:@FSM%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.AGENT.ARRAY:@ARRAY-AGENT%20MGL-PAX:SECTION" title="Array/Vector agent">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.STASH:@STASHING%20MGL-PAX:SECTION" title="Stashing">&#8594;</a> <a href="#SENTO.FSM:@FSM%20MGL-PAX:SECTION" title="Finite state machine">&#8634;</a></span></span></p>
<h3><a href="#SENTO.FSM:@FSM%20MGL-PAX:SECTION">2.5 Finite state machine</a></h3>
<h6>[in package SENTO.FSM with nicknames FSM]</h6>
<p><a id="x-28SENTO-2EFSM-3AFSM-20CLASS-29"></a>
<a id="SENTO.FSM:FSM%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.FSM:FSM%20CLASS" >FSM</a></span></span> <span class="locative-args"><a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS">ACTOR</a></span></span></p>

<p><a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> Class</p>

<p>The <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> class represents a Finite State Machine, a mathematical model of computation that transitions between a finite number of states in response to external inputs.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AMAKE-FSM-20FUNCTION-29"></a>
<a id="SENTO.FSM:MAKE-FSM%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.FSM:MAKE-FSM%20FUNCTION" >MAKE-FSM</a></span></span> <span class="locative-args">ACTOR-CONTEXT &amp;KEY NAME START-WITH EVENT-HANDLING (TYPE '<a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a>) (DISPATCHER-ID <code>:SHARED</code>)</span></span></p>

<p><a href="#SENTO.FSM:MAKE-FSM%20FUNCTION" title="SENTO.FSM:MAKE-FSM FUNCTION"><code>make-fsm</code></a> Function</p>

<p>Creates a finite state machine (<a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a>) within the given <code>actor-context</code>.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>actor-context</code>: Can be an actor, an actor-context (class), or an actor-system in which this <code>FSM</code> is created.</p></li>
<li><p><code>name</code>: A string representing the name of the <code>FSM</code>. Must be a string.</p></li>
<li><p><code>start-with</code>: A cons cell where the car is the initial state and the cdr is the initial data for the <code>FSM</code>. Must be a cons.</p></li>
<li><p><code>event-handling</code>: An optional function for handling events. It can be <code>nil</code> if not provided. Must be either a function or <code>nil</code>. If omitted, the <code>FSM</code> will effectively do nothing. The function body should be constructed using the provided <code>FSM</code>-related macros such as <a href="#SENTO.FSM:ON-EVENT%20MGL-PAX:MACRO" title="SENTO.FSM:ON-EVENT MGL-PAX:MACRO"><code>on-event</code></a> and <a href="#SENTO.FSM:ON-TRANSITION%20MGL-PAX:MACRO" title="SENTO.FSM:ON-TRANSITION MGL-PAX:MACRO"><code>on-transition</code></a>.</p></li>
<li><p><code>type</code>: The type of actor to create. Defaults to <code>'fsm</code>.</p></li>
<li><p><code>dispatcher-id</code>: Identifies the dispatcher for the <code>FSM</code>. Defaults to <code>:shared</code>.</p></li>
</ul>

<p><strong>Description</strong></p>

<p>The <a href="#SENTO.FSM:MAKE-FSM%20FUNCTION" title="SENTO.FSM:MAKE-FSM FUNCTION"><code>make-fsm</code></a> function initializes an <code>FSM</code> actor with a specified initial state and associated data. The <code>FSM</code>'s behavior is defined by the <code>event-handling</code> function, which processes events if provided. This function should utilize the provided macros like <code>on-event</code> and <code>on-transition</code> to structure its body, enabling robust event handling and state transition management. Without this function, the <code>FSM</code> will not perform any actions.</p>

<p>This function configures the <code>FSM</code> within the given <code>actor-context</code>, ensuring it is properly set up according to the parameters specified through the <a href="#SENTO.ACTOR-CONTEXT:ACTOR-OF%20GENERIC-FUNCTION" title="SENTO.ACTOR-CONTEXT:ACTOR-OF GENERIC-FUNCTION"><code>ac:actor-of</code></a> function.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AWHEN-STATE-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:WHEN-STATE%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:WHEN-STATE%20MGL-PAX:MACRO" >WHEN-STATE</a></span></span> <span class="locative-args">(STATE &amp;KEY (TEST '#'<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>EQ</code></a>) TIMEOUT-S) &amp;BODY BODY</span></span></p>

<p><code>when-state</code> Macro</p>

<p>The <code>when-state</code> macro is used to conditionally execute a body of code when a defined condition on the <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a>'s (Finite State Machine) current state is met, with support for custom predicates and timeout management for nested <a href="#SENTO.FSM:ON-EVENT%20MGL-PAX:MACRO" title="SENTO.FSM:ON-EVENT MGL-PAX:MACRO"><code>on-event</code></a> macros.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>state</code>: An arbitrary value or structure that represents the state to be checked against the <code>FSM</code>'s current state. The usage and type should align with the <code>:test</code> function.</p></li>
<li><p><code>:test</code>: A predicate function used to evaluate if the <code>FSM</code>'s current state matches the <code>state</code> argument. The default is <code>#'eq</code>, but can be customized with other functions or lambdas.</p></li>
<li><p><code>:timeout-s</code>: An optional timeout in seconds that is applied to <code>on-event</code> macro calls tagged with <code>:state-timeout</code> within the body.</p></li>
<li><p><code>body</code>: One or more forms, typically including <code>on-event</code> macro definitions, executed if the state condition is satisfied.</p></li>
</ul>

<p><strong>Description</strong></p>

<p><code>when-state</code> enables dynamic state-based programming within <code>FSM</code>s, allowing for flexible condition evaluation with customizable predicate functions. It also manages execution timeouts for actions specified within nested <code>on-event</code> calls. The <code>:timeout-s</code> parameter, when used with the <code>:state-timeout</code> tag, ensures operations are constrained to a specified period.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'active <span class="keyword">:test</span> #'eq <span class="keyword">:timeout-s</span> 10</span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'start</span>)</span> <span class="keyword">:state-timeout</span>
    <span class="paren3">(<span class="code">start-activity</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'stop</span>)</span>
    <span class="paren3">(<span class="code">stop-activity</span>)</span></span>)</span></span>)</span></span></code></pre>

<p>In this example:
- <code>start-activity</code> is executed if the current <code>FSM</code> state is exactly <code>'active</code>, using <code>:test #'eq</code>, within the 10-second window specified by <code>:timeout-s</code> and tagged with <code>:state-timeout</code>.
- <code>stop-activity</code> runs upon receiving a <code>stop</code> event, without timeout constraints.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p>Adjust the <code>:test</code> predicate to suit the structure and type of your <code>state</code> input as needed.</p></li>
<li><p><code>:timeout-s</code> specifies a duration within which tagged events should occur, integrating with the <code>on-event</code> macro.</p></li>
<li><p>Ensure that each <code>on-event</code> is properly enclosed in parentheses, reflecting its syntax.</p></li>
</ul>

<p>Use the appropriate predicate function to match the <code>state</code> argument's format, ensuring meaningful and effective <code>FSM</code> operations.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AON-EVENT-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:ON-EVENT%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:ON-EVENT%20MGL-PAX:MACRO" >ON-EVENT</a></span></span> <span class="locative-args">(EVENT &amp;KEY (TEST '#'<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>EQ</code></a>)) &amp;BODY BODY</span></span></p>

<p><code>on-event</code> Macro</p>

<p>The <code>on-event</code> macro defines actions to be executed when specific events occur within an <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> (Finite State Machine). It is often used within the <a href="#SENTO.FSM:WHEN-STATE%20MGL-PAX:MACRO" title="SENTO.FSM:WHEN-STATE MGL-PAX:MACRO"><code>when-state</code></a> macro to enable conditional execution based on state and optional timeout constraints.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>event</code>: The event name or identifier to be monitored. This argument specifies which event should trigger the execution of the provided body.</p></li>
<li><p><code>:state-timeout</code>: A tag indicating that the execution of this event's actions is subject to the <code>:timeout-s</code> specified in a surrounding <code>when-state</code> macro.</p></li>
<li><p><code>body</code>: One or more expressions representing the actions to be executed when the specified event occurs.</p></li>
</ul>

<p><strong>Description</strong></p>

<p>The <code>on-event</code> macro facilitates event-driven actions within <code>FSM</code>s. When used within a <code>when-state</code> block and tagged with <code>:state-timeout</code>, it ensures that the actions are executed within a specified time period after the event occurs, contingent on the current state of the <code>FSM</code>.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'active <span class="keyword">:test</span> #'eq <span class="keyword">:timeout-s</span> 10</span>)</span>
  <span class="paren2">(<span class="code">on-event 'start <span class="keyword">:state-timeout</span>
    <span class="paren3">(<span class="code">start-activity</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">on-event 'stop
    <span class="paren3">(<span class="code">stop-activity</span>)</span></span>)</span></span>)</span></span></code></pre>

<p>In this example:
- The <code>start-activity</code> action is executed when the <code>start</code> event occurs, provided the <code>FSM</code> is in the <code>active</code> state within the 10-second timeout duration.
- The <code>stop-activity</code> is triggered by a <code>stop</code> event without timeout constraints.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p><code>:state-timeout</code> indicates that the timeout from <code>when-state</code> should apply to this event's execution.</p></li>
<li><p>Ensure the event detection mechanism within your <code>FSM</code> can recognize and handle the specified <code>event</code> argument.</p></li>
</ul>

<p>Use <code>on-event</code> macros within <code>when-state</code> to manage event responses systematically and within time constraints defined for specific states. Adjust the actions and logic as necessary for your <code>FSM</code>'s behavior.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AGOTO-STATE-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:GOTO-STATE%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:GOTO-STATE%20MGL-PAX:MACRO" >GOTO-STATE</a></span></span> <span class="locative-args">NEXT-STATE &amp;OPTIONAL (DATA <code>NIL</code>)</span></span></p>

<p><code>goto-state</code> Macro</p>

<p>The <code>goto-state</code> macro is used to transition the <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> (Finite State Machine) to a specified state, with optional data setting for the state model. This macro simplifies state management by providing a direct mechanism to switch states and update state-specific data.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>state</code>: The target state to which the <code>FSM</code> should transition. This can be a symbol or any other datatype representing the state, consistent with the <code>FSM</code>'s state representation.</p></li>
<li><p><code>data</code>: An optional parameter to set the data associated with the new state. This allows for updating the state model with relevant information during the transition.</p></li>
</ul>

<p><strong>Description</strong></p>

<p>The <code>goto-state</code> macro facilitates explicit state transitions and optionally updates the state model's data. It is typically invoked in response to specific conditions or events, allowing dynamic integration with other <code>FSM</code> constructs like <a href="#SENTO.FSM:WHEN-STATE%20MGL-PAX:MACRO" title="SENTO.FSM:WHEN-STATE MGL-PAX:MACRO"><code>when-state</code></a> or <a href="#SENTO.FSM:ON-EVENT%20MGL-PAX:MACRO" title="SENTO.FSM:ON-EVENT MGL-PAX:MACRO"><code>on-event</code></a>.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'idle <span class="keyword">:test</span> #'eq <span class="keyword">:timeout-s</span> 5</span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'start</span>)</span>
    <span class="paren3">(<span class="code">goto-state 'active '<span class="paren4">(<span class="code"><span class="string">"Session ID: 123"</span></span>)</span></span>)</span>
    <span class="paren3">(<span class="code">perform-initialization</span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'active <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'stop</span>)</span>
    <span class="paren3">(<span class="code">goto-state 'idle '<span class="paren4">(<span class="code"><span class="string">"Clean exit"</span></span>)</span></span>)</span>
    <span class="paren3">(<span class="code">perform-cleanup</span>)</span></span>)</span></span>)</span></span></code></pre>

<p>In this example:
- The <code>FSM</code> transitions to the <code>active</code> state with associated data <code>&quot;Session ID: 123&quot;</code> upon receiving a <code>start</code> event while in the <code>idle</code> state, executing <code>perform-initialization</code>.
- It transitions back to the <code>idle</code> state with data <code>&quot;Clean exit&quot;</code> when the <code>stop</code> event occurs while the <code>FSM</code> is in the <code>active</code> state, executing <code>perform-cleanup</code>.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p>Ensure that <code>state</code> is valid within the <code>FSM</code>'s state space and that the transition complies with the <code>FSM</code>'s logic and rules.</p></li>
<li><p>The <code>data</code> parameter is optional, but when used, should be structured appropriately to fit the state model's requirements.</p></li>
</ul>

<p>The <code>goto-state</code> macro, with its optional <code>data</code> capability, enhances flexibility and precision in managing <code>FSM</code> state transitions and data updates. Adjust the usage examples and structure to align with your <code>FSM</code>'s specific needs and design.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3ASTAY-ON-STATE-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:STAY-ON-STATE%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:STAY-ON-STATE%20MGL-PAX:MACRO" >STAY-ON-STATE</a></span></span> <span class="locative-args">&amp;OPTIONAL (DATA <code>NIL</code>)</span></span></p>

<p><code>stay-on-state</code> Macro</p>

<p>The <code>stay-on-state</code> macro is used to maintain the <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> (Finite State Machine) in its current state, with an option to update the state's associated data. This is useful for situations where the state needs to persist while its data is updated.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><code>data</code>: An optional parameter to update the data related to the current state. This allows for modifying the state model with new information without changing the state itself.</li>
</ul>

<p><strong>Description</strong></p>

<p>The <code>stay-on-state</code> macro provides a way to remain in the current state of an <code>FSM</code> while updating any associated data. It can be used in reaction to specific events or conditions, maintaining state continuity while making data adjustments.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'processing <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'update</span>)</span>
    <span class="paren3">(<span class="code">stay-on-state '<span class="paren4">(<span class="code"><span class="string">"Progress: 50%"</span></span>)</span></span>)</span>
    <span class="paren3">(<span class="code">log-update</span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code">when-state <span class="paren2">(<span class="code">'processing <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">on-event <span class="paren3">(<span class="code">'complete</span>)</span>
    <span class="paren3">(<span class="code">goto-state 'completed '<span class="paren4">(<span class="code"><span class="string">"Finished successfully"</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>

<p>In this example:
- The <code>stay-on-state</code> macro is used to remain in the <code>processing</code> state while updating the progress data to <code>&quot;Progress: 50%&quot;</code> upon an <code>update</code> event.
- Transition to the <code>completed</code> state occurs when the <code>complete</code> event is triggered, updating the state and its data.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p>The <code>data</code> parameter is optional but should be structured to fit the requirements of the state model.</p></li>
<li><p>Use this macro to ensure state persistence with updated data when necessary.</p></li>
</ul>

<p>Integrate the <code>stay-on-state</code> macro into your <code>FSM</code> to handle cases where the state should remain unchanged but its data requires updates. Adjust examples as needed to fit your <code>FSM</code> system.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AWHEN-UNHANDLED-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:WHEN-UNHANDLED%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:WHEN-UNHANDLED%20MGL-PAX:MACRO" >WHEN-UNHANDLED</a></span></span> <span class="locative-args">(EVENT &amp;KEY (TEST '#'<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>EQ</code></a>)) &amp;BODY BODY</span></span></p>

<p><code>when-unhandled</code> Macro</p>

<p>The <code>when-unhandled</code> macro defines actions to be executed when an event has not been handled by any prior <a href="#SENTO.FSM:STAY-ON-STATE%20MGL-PAX:MACRO" title="SENTO.FSM:STAY-ON-STATE MGL-PAX:MACRO"><code>stay-on-state</code></a> or <a href="#SENTO.FSM:GOTO-STATE%20MGL-PAX:MACRO" title="SENTO.FSM:GOTO-STATE MGL-PAX:MACRO"><code>goto-state</code></a> operations within an <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> (Finite State Machine).</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>event</code>: The event that should trigger the body if it remains unhandled by other mechanisms in the <code>FSM</code>.</p></li>
<li><p><code>:test</code>: A key parameter specifying the function used to compare the received event with the specified event. Defaults to <code>#'eq</code>, allowing for custom comparison logic.</p></li>
<li><p><code>body</code>: One or more expressions to execute when the specified event is unhandled by <code>stay-on-state</code> or <code>goto-state</code> actions.</p></li>
</ul>

<p><strong>Description</strong></p>

<p>The <code>when-unhandled</code> macro is designed to catch events that have not been processed by <code>stay-on-state</code> or <code>goto-state</code>. It provides a fallback mechanism that ensures specific actions are taken for such unhandled events, using a specified test function to determine event equivalency.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">when-unhandled <span class="paren2">(<span class="code">'start <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">log:error <span class="string">"Start event was unhandled"</span></span>)</span>
  <span class="paren2">(<span class="code">notify-admin</span>)</span></span>)</span>

<span class="paren1">(<span class="code">when-unhandled <span class="paren2">(<span class="code">'disconnect <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">log:warn <span class="string">"Unhandled disconnect event"</span></span>)</span>
  <span class="paren2">(<span class="code">attempt-reconnect</span>)</span></span>)</span></span></code></pre>

<p>In these examples:
- The first block logs an error and notifies an admin if the <code>start</code> event remains unhandled, using the default <code>#'eq</code> function for testing.
- The second block logs a warning and attempts to reconnect for an unhandled <code>disconnect</code> event, also using <code>#'eq</code>.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p>Utilize the <code>test</code> parameter to customize how events are determined as equivalent when necessary.</p></li>
<li><p><code>when-unhandled</code> is essential for capturing and managing scenarios where standard state transitions do not account for all event possibilities.</p></li>
<li><p>Is it possible to use <code>goto-state</code> in <code>body</code>.</p></li>
</ul>

<p>Integrate the <code>when-unhandled</code> macro to ensure your <code>FSM</code> handles any unexpected or default cases robustly and flexibly. Adjust the body actions and events as needed for your specific requirements and <code>FSM</code> design.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3AON-TRANSITION-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FSM:ON-TRANSITION%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FSM:ON-TRANSITION%20MGL-PAX:MACRO" >ON-TRANSITION</a></span></span> <span class="locative-args">(TRANSITION &amp;KEY (TEST '#'<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>EQ</code></a>)) &amp;BODY BODY</span></span></p>

<p><code>on-transition</code> Macro</p>

<p>The <code>on-transition</code> macro defines actions to be executed when a specific state transition occurs within an <a href="#SENTO.FSM:FSM%20CLASS" title="SENTO.FSM:FSM CLASS"><code>FSM</code></a> (Finite State Machine). It uses customizable test functions to determine when a transition has taken place.</p>

<p><strong>Parameters</strong></p>

<ul>
<li><p><code>transition</code>: A cons cell or similar paired structure representing the transition, with the car as the starting state and the cdr as the destination state.</p></li>
<li><p><code>:test</code>: A key parameter specifying the function used to compare states. Defaults to <code>#'eq</code>, allowing for custom comparison logic if needed.</p></li>
<li><p><code>body</code>: One or more expressions that are executed when the specified transition is detected.</p></li>
</ul>

<p><strong>Description</strong></p>

<p>The <code>on-transition</code> macro provides a mechanism for executing specific actions when the <code>FSM</code> undergoes a particular state transition, as identified by changes in the state model from a starting to an ending state. This macro depends on events being handled by a state transition (<a href="#SENTO.FSM:GOTO-STATE%20MGL-PAX:MACRO" title="SENTO.FSM:GOTO-STATE MGL-PAX:MACRO"><code>goto-state</code></a>), and uses test functions to match state values.</p>

<p><strong>Usage Example</strong></p>

<pre><code><span class="code"><span class="paren1">(<span class="code">on-transition <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">'idle . 'active</span>)</span> <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">log:info <span class="string">"Transitioned from idle to active"</span></span>)</span>
  <span class="paren2">(<span class="code">initialize-resources</span>)</span></span>)</span>

<span class="paren1">(<span class="code">on-transition <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">'active . 'completed</span>)</span> <span class="keyword">:test</span> #'eq</span>)</span>
  <span class="paren2">(<span class="code">log:info <span class="string">"Transitioned from active to completed"</span></span>)</span>
  <span class="paren2">(<span class="code">cleanup-resources</span>)</span></span>)</span></span></code></pre>

<p>In these examples:
- The first block logs the transition from <code>idle</code> to <code>active</code> and performs resource initialization when this transition occurs.
- The second block logs the transition from <code>active</code> to <code>completed</code> and performs cleanup.</p>

<p><strong>Notes</strong></p>

<ul>
<li><p><code>:test</code>: Customize the comparison logic to fit the <code>FSM</code>'s state representations, especially if using complex or non-standard states.</p></li>
<li><p>The macro relies on transitions being marked by the handling of events through <code>goto-state</code>.</p></li>
</ul>

<p>Utilize the <code>on-transition</code> macro to effectively manage and isolate logic specific to state transitions, ensuring that your <code>FSM</code> operates smoothly and predictably through defined state changes. Adjust the body of transitions to align with the goals and behavior of your <code>FSM</code> system.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3A-2ARECEIVED-EVENT-2A-20VARIABLE-29"></a>
<a id="SENTO.FSM:*RECEIVED-EVENT*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.FSM:*RECEIVED-EVENT*%20VARIABLE" >*RECEIVED-EVENT*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Dynamically binds the received event (message).</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3A-2AEVENT-DATA-2A-20VARIABLE-29"></a>
<a id="SENTO.FSM:*EVENT-DATA*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.FSM:*EVENT-DATA*%20VARIABLE" >*EVENT-DATA*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Dynamically binds event data when msg/event was sent with data (`cons')</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3A-2ASTATE-DATA-2A-20VARIABLE-29"></a>
<a id="SENTO.FSM:*STATE-DATA*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.FSM:*STATE-DATA*%20VARIABLE" >*STATE-DATA*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Dynamically binds the current state data.</p></li>
</ul>
<p><a id="x-28SENTO-2EFSM-3A-2ANEXT-STATE-DATA-2A-20VARIABLE-29"></a>
<a id="SENTO.FSM:*NEXT-STATE-DATA*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.FSM:*NEXT-STATE-DATA*%20VARIABLE" >*NEXT-STATE-DATA*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Dynamically binds the next state data (<code>on-transition').
Effectively same as</code><em>event-data</em>' but should be used in different context.</p></li>
</ul>
<p><a id="x-28SENTO-2ESTASH-3A-40STASHING-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.STASH:@STASHING%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.FSM:@FSM%20MGL-PAX:SECTION" title="Finite state machine">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION" title="Dispatcher">&#8594;</a> <a href="#SENTO.STASH:@STASHING%20MGL-PAX:SECTION" title="Stashing">&#8634;</a></span></span></p>
<h3><a href="#SENTO.STASH:@STASHING%20MGL-PAX:SECTION">2.6 Stashing</a></h3>
<h6>[in package SENTO.STASH with nicknames STASH]</h6>
<p><a id="x-28SENTO-2ESTASH-3ASTASHING-20CLASS-29"></a>
<a id="SENTO.STASH:STASHING%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.STASH:STASHING%20CLASS" >STASHING</a></span></span></span></p>

<p><code>stashing</code> is a mixin class to <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>act:actor</code></a>.
It can 'stash' away arriving messages which should not be handled now, but later, after the actor is 'able' to handle them. Create an actor class that can stash like this:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defclass</span></i> stash-actor <span class="paren2">(<span class="code">actor stashing</span>)</span> <span class="paren2">(<span class="code"></span>)</span></span>)</span></span></code></pre>

<p>Then create an actor by specifying this type:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">actor-of system
          <span class="keyword">:type</span> 'stash-actor
          <span class="keyword">:receive</span> <span class="paren2">(<span class="code"><i><span class="symbol">lambda</span></i> <span class="paren3">(<span class="code">msg</span>)</span>
                     ...</span>)</span></span>)</span></span></code></pre>

<p>For stash and unstash see function descriptions below.</p>

<p>The main use-case is for <a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" title="SENTO.ACTOR:TELL GENERIC-FUNCTION"><code>act:tell</code></a> and <a href="#SENTO.ACTOR:ASK%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK GENERIC-FUNCTION"><code>act:ask</code></a>. <a href="#SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK-S GENERIC-FUNCTION"><code>act:ask-s</code></a> will not work.
timeouts are ignored because it is not clear how long stashed messages will reside in stash.
However the <code>sender</code>, if given (on <code>act:tell</code>), is preserved.</p></li>
</ul>
<p><a id="x-28SENTO-2ESTASH-3ASTASH-20FUNCTION-29"></a>
<a id="SENTO.STASH:STASH%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.STASH:STASH%20FUNCTION" >STASH</a></span></span> <span class="locative-args">MSG</span></span></p>

<p>Stash <code>msg</code> for later unstash.
On stashing a message the actor should respond with: <code>(cons :no-reply state)</code>
to avoid returning a response to sender (if given).</p>

<p>This function is expected to be run from within 'receive' function.</p></li>
</ul>
<p><a id="x-28SENTO-2ESTASH-3AUNSTASH-ALL-20FUNCTION-29"></a>
<a id="SENTO.STASH:UNSTASH-ALL%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.STASH:UNSTASH-ALL%20FUNCTION" >UNSTASH-ALL</a></span></span></span></p>

<p>Unstash all messages.
Messages are re-submitted to the actor in the order they were stashed.
Resubmitting means they are added to the end of the queue like any ordinary message would.</p>

<p>This function is expected to be run from within 'receive' function.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3A-40DISPATCHER-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.STASH:@STASHING%20MGL-PAX:SECTION" title="Stashing">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION" title="Shared dispatcher">&#8594;</a> <a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION" title="Dispatcher">&#8634;</a></span></span></p>
<h3><a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION">2.7 Dispatcher</a></h3>
<h6>[in package SENTO.DISPATCHER with nicknames DISP]</h6>
<p><a id="x-28SENTO-2EDISPATCHER-3ADISPATCHER-BASE-20CLASS-29"></a>
<a id="SENTO.DISPATCHER:DISPATCHER-BASE%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:DISPATCHER-BASE%20CLASS" >DISPATCHER-BASE</a></span></span></span></p>

<p>A <code>dispatcher</code> contains a pool of <code>actors</code> that operate as workers where work is dispatched to.
However, the workers are created in the given <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3AIDENTIFIER-20-28MGL-PAX-3AREADER-20SENTO-2EDISPATCHER-3ADISPATCHER-BASE-29-29"></a>
<a id="SENTO.DISPATCHER:IDENTIFIER%20%28MGL-PAX:READER%20SENTO.DISPATCHER:DISPATCHER-BASE%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[reader]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:IDENTIFIER%20%28MGL-PAX:READER%20SENTO.DISPATCHER:DISPATCHER-BASE%29" >IDENTIFIER</a></span></span> <span class="locative-args">DISPATCHER-BASE (:IDENTIFIER = NIL)</span></span></p>

<p>Returns the identifier of the dispatcher.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3AMAKE-DISPATCHER-20FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:MAKE-DISPATCHER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:MAKE-DISPATCHER%20FUNCTION" >MAKE-DISPATCHER</a></span></span> <span class="locative-args">ACTOR-CONTEXT IDENTIFIER &amp;REST CONFIG</span></span></p>

<p>Default constructor.
This creates a <a href="#SENTO.DISPATCHER:SHARED-DISPATCHER%20CLASS" title="SENTO.DISPATCHER:SHARED-DISPATCHER CLASS"><code>disp:shared-dispatcher</code></a> with the given dispatcher config, see <a href="#SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE" title="SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG* VARIABLE"><code>asys:*default-config*</code></a>.
Each worker is based on a <code>:pinned</code> actor meaning that it has its own thread.
Specify an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> where actors needed in the dispatcher are created in.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3ADISPATCH-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:DISPATCH%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:DISPATCH%20GENERIC-FUNCTION" >DISPATCH</a></span></span> <span class="locative-args">DISPATCHER DISPATCHER-EXEC-FUN</span></span></p>

<p>Dispatches a function (<code>dispatch-exec-fun</code>) to a worker of the dispatcher to execute there.
<code>dispatch</code> does a <code>ask-s</code> to a <code>dispatcher</code> worker, which means this call will block.
The parameter <code>dispatcher-exec-fun</code> if of the form: <code>(list (function &lt;something&gt;))</code></p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3ADISPATCH-ASYNC-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:DISPATCH-ASYNC%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:DISPATCH-ASYNC%20GENERIC-FUNCTION" >DISPATCH-ASYNC</a></span></span> <span class="locative-args">DISPATCHER DISPATCHER-EXEC-FUN</span></span></p>

<p>Dispatches a function to a worker of the dispatcher to execute there.
<code>dispatch-async</code> does a <code>tell</code> to a <code>dispatcher</code> worker and is asynchronous.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3ASTOP-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:STOP%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:STOP%20GENERIC-FUNCTION" >STOP</a></span></span> <span class="locative-args">DISPATCHER</span></span></p>

<p>Stops the dispatcher. Stops all workers.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3AWORKERS-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:WORKERS%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:WORKERS%20GENERIC-FUNCTION" >WORKERS</a></span></span> <span class="locative-args">DISPATCHER</span></span></p>

<p>Returns the workers of this dispatcher.
But better do not touch them.
Only use the defined interface here to talk to them.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3ADISPATCH-WORKER-20CLASS-29"></a>
<a id="SENTO.DISPATCHER:DISPATCH-WORKER%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:DISPATCH-WORKER%20CLASS" >DISPATCH-WORKER</a></span></span> <span class="locative-args"><a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS">SENTO.ACTOR:ACTOR</a></span></span></p>

<p>Specialized <code>actor</code> used as <code>worker</code> is the message <code>dispatcher</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3AMAKE-DISPATCHER-WORKER-20FUNCTION-29"></a>
<a id="SENTO.DISPATCHER:MAKE-DISPATCHER-WORKER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:MAKE-DISPATCHER-WORKER%20FUNCTION" >MAKE-DISPATCHER-WORKER</a></span></span> <span class="locative-args">NUM ACTOR-CONTEXT DISPATCHER-IDENT</span></span></p>

<p>Constructor for creating a worker.
<code>num</code> only has the purpose to give the worker a name which includes a number.
`dispatcher-ident is the dispatcher identifier.</p></li>
</ul>
<p><a id="x-28SENTO-2EDISPATCHER-3A-40SHARED-DISPATCHER-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION" title="Dispatcher">&#8592;</a> <a href="#SENTO.DISPATCHER:@DISPATCHER%20MGL-PAX:SECTION" title="Dispatcher">&#8593;</a> <a href="#SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION" title="Router">&#8594;</a> <a href="#SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION" title="Shared dispatcher">&#8634;</a></span></span></p>
<h4><a href="#SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION">2.7.1 Shared dispatcher</a></h4>
<p><a id="x-28SENTO-2EDISPATCHER-3ASHARED-DISPATCHER-20CLASS-29"></a>
<a id="SENTO.DISPATCHER:SHARED-DISPATCHER%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.DISPATCHER:SHARED-DISPATCHER%20CLASS" >SHARED-DISPATCHER</a></span></span> <span class="locative-args"><a href="#SENTO.DISPATCHER:DISPATCHER-BASE%20CLASS" title="SENTO.DISPATCHER:DISPATCHER-BASE CLASS">DISPATCHER-BASE</a></span></span></p>

<p>A shared dispatcher.
Internally it uses a <a href="#SENTO.ROUTER:ROUTER%20CLASS" title="SENTO.ROUTER:ROUTER CLASS"><code>router:router</code></a> to drive the <a href="#SENTO.DISPATCHER:DISPATCH-WORKER%20CLASS" title="SENTO.DISPATCHER:DISPATCH-WORKER CLASS"><code>dispatch-worker</code></a>s.
The default strategy of choosing a worker is <code>:random</code>.</p>

<p>A <code>shared-dispatcher</code> is automatically setup by an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EROUTER-3A-40ROUTER-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.DISPATCHER:@SHARED-DISPATCHER%20MGL-PAX:SECTION" title="Shared dispatcher">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION" title="Eventstream">&#8594;</a> <a href="#SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION" title="Router">&#8634;</a></span></span></p>
<h3><a href="#SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION">2.8 Router</a></h3>
<h6>[in package SENTO.ROUTER with nicknames ROUTER]</h6>
<p><a id="x-28SENTO-2EROUTER-3AROUTER-20CLASS-29"></a>
<a id="SENTO.ROUTER:ROUTER%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.ROUTER:ROUTER%20CLASS" >ROUTER</a></span></span></span></p>

<p>A router combines a pool of actors and implements the actor-api protocol.
So a <a href="#SENTO.ACTOR:TELL%20GENERIC-FUNCTION" title="SENTO.ACTOR:TELL GENERIC-FUNCTION"><code>tell</code></a>, <a href="#SENTO.ACTOR:ASK-S%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK-S GENERIC-FUNCTION"><code>ask-s</code></a> and <a href="#SENTO.ACTOR:ASK%20GENERIC-FUNCTION" title="SENTO.ACTOR:ASK GENERIC-FUNCTION"><code>ask</code></a> is delegated to one of the routers routees.
While a router implements parts of the actor protocol it doesn't implement all.
I.e. a router cannot be <code>watch</code>ed.
A router <code>strategy</code> defines how one of the actors is determined as the forwarding target of the message.</p></li>
</ul>
<p><a id="x-28SENTO-2EROUTER-3AMAKE-ROUTER-20FUNCTION-29"></a>
<a id="SENTO.ROUTER:MAKE-ROUTER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ROUTER:MAKE-ROUTER%20FUNCTION" >MAKE-ROUTER</a></span></span> <span class="locative-args">&amp;KEY (STRATEGY <code>:RANDOM</code>) (ROUTEES <code>NIL</code>)</span></span></p>

<p>Default constructor of router.
Built-in strategies: <code>:random</code>, <code>:round-robin</code>.
Specify your own strategy by providing a function that takes a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_fixnum.htm" title="FIXNUM (MGL-PAX:CLHS TYPE)"><code>fixnum</code></a> as parameter which represents the number of routees and returns a <code>fixnum</code> that represents the index of the routee to choose.</p>

<p>Specify <code>routees</code> if you know them upfront.</p></li>
</ul>
<p><a id="x-28SENTO-2EROUTER-3AADD-ROUTEE-20FUNCTION-29"></a>
<a id="SENTO.ROUTER:ADD-ROUTEE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ROUTER:ADD-ROUTEE%20FUNCTION" >ADD-ROUTEE</a></span></span> <span class="locative-args">ROUTER ROUTEE</span></span></p>

<p>Adds a routee/actor to the router.</p></li>
</ul>
<p><a id="x-28SENTO-2EROUTER-3ASTOP-20FUNCTION-29"></a>
<a id="SENTO.ROUTER:STOP%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ROUTER:STOP%20FUNCTION" >STOP</a></span></span> <span class="locative-args">ROUTER</span></span></p>

<p>Stops all routees.</p></li>
</ul>
<p><a id="x-28SENTO-2EROUTER-3AROUTEES-20FUNCTION-29"></a>
<a id="SENTO.ROUTER:ROUTEES%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.ROUTER:ROUTEES%20FUNCTION" >ROUTEES</a></span></span> <span class="locative-args">ROUTER</span></span></p>

<p>Returns the routees as list.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3ATELL-20-28METHOD-20NIL-20-28SENTO-2EROUTER-3AROUTER-20T-29-29-29"></a>
<a id="SENTO.ACTOR:TELL%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR:TELL%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29" >TELL</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ROUTER:ROUTER%20CLASS" title="SENTO.ROUTER:ROUTER CLASS"><code>ROUTER</code></a>) MESSAGE</span></span></p>

<p>Posts the message to one routee. The routee is chosen from the router <code>strategy</code>.
Otherwise see: <code>act:tell</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AASK-S-20-28METHOD-20NIL-20-28SENTO-2EROUTER-3AROUTER-20T-29-29-29"></a>
<a id="SENTO.ACTOR:ASK-S%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR:ASK-S%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29" >ASK-S</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ROUTER:ROUTER%20CLASS" title="SENTO.ROUTER:ROUTER CLASS"><code>ROUTER</code></a>) MESSAGE</span></span></p>

<p>Posts the message to one routee. The routee is chosen from the router <code>strategy</code>.
Otherwise see: <code>act:ask-s</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EACTOR-3AASK-20-28METHOD-20NIL-20-28SENTO-2EROUTER-3AROUTER-20T-29-29-29"></a>
<a id="SENTO.ACTOR:ASK%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.ACTOR:ASK%20%28METHOD%20NIL%20%28SENTO.ROUTER:ROUTER%20T%29%29" >ASK</a></span></span> <span class="locative-args">(SELF <a href="#SENTO.ROUTER:ROUTER%20CLASS" title="SENTO.ROUTER:ROUTER CLASS"><code>ROUTER</code></a>) MESSAGE</span></span></p>

<p>Posts the message to one routee. The routee is chosen from the router <code>strategy</code>.
Otherwise see: <code>act:ask</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3A-40EVENTSTREAM-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.ROUTER:@ROUTER%20MGL-PAX:SECTION" title="Router">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION" title="Future (delayed-computation)">&#8594;</a> <a href="#SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION" title="Eventstream">&#8634;</a></span></span></p>
<h3><a href="#SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION">2.9 Eventstream</a></h3>
<h6>[in package SENTO.EVENTSTREAM with nicknames EV]</h6>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AEVENTSTREAM-20CLASS-29"></a>
<a id="SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" >EVENTSTREAM</a></span></span></span></p>

<p>Eventstream facility allows to post/publish messages/events in the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> and actors that did subscribe, to listen on those events.</p>

<p>The eventstream is driven by an actor. The processing of the sent events is guaranteed to be as they arrive.</p>

<p>Events can be posted as plain strings, as lists, or as objects of classes.
The subscriber has a variaty of options to define what to listen for.</p>

<p>For example: a subscriber wants to listen to events/messages with the string &quot;Foo&quot;.
The subscriber is then only notified when events are posted with the exact same string.</p>

<p>See more information at the <a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20GENERIC-FUNCTION" title="SENTO.EVENTSTREAM:SUBSCRIBE GENERIC-FUNCTION"><code>ev:subscribe</code></a> function.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AMAKE-EVENTSTREAM-20FUNCTION-29"></a>
<a id="SENTO.EVENTSTREAM:MAKE-EVENTSTREAM%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:MAKE-EVENTSTREAM%20FUNCTION" >MAKE-EVENTSTREAM</a></span></span> <span class="locative-args">ACTOR-CONTEXT &amp;REST CONFIG</span></span></p>

<p>Creating an eventstream is done by the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> which is then available system wide. 
But in theory it can be created individually by just passing an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a> (though I don't know what would be the reason to create an eventstream for the context of a single actor. Maybe to address only a certain hierarchy in the actor tree.)</p>

<ul>
<li><p><code>actor-context</code>: the <code>ac:actor-context</code> where the eventstream actor should be created in.</p></li>
<li><p><code>config</code>: is a plist with the <code>:dispatcher-id</code> key and a dispatcher id as value. Defaults to <code>:shared</code>. This dispatcher type should be used by the actor.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3ASUBSCRIBE-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.EVENTSTREAM:SUBSCRIBE%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20GENERIC-FUNCTION" >SUBSCRIBE</a></span></span> <span class="locative-args">EVENTSTREAM SUBSCRIBER &amp;OPTIONAL PATTERN</span></span></p>

<p>Subscribe to the eventstream to receive notifications of certain events or event types.</p>

<p><code>subscriber</code> must be an actor (or agent).</p>

<p>The <code>pattern</code> can be:</p>

<ul>
<li><p>nil: receive all events posted to the eventstream.</p></li>
<li><p>a type, class type: this allows to get notifications when an instance of this type, or class type is posted.
I.e. if you want to listen to all string messages posted to the ev, thewn subscribe to <code>'string</code>.
Or if you want to listen to all lists, subscribe with <code>'cons</code>.</p></li>
<li><p>a symbol or global symbol: if posted message is a symbol or global symbol then the symbols are compared (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm" title="EQ (MGL-PAX:CLHS FUNCTION)"><code>eq</code></a>).</p></li>
<li><p>a string: in which case an exact string comparison is made for a string message that is posted to the eventstream (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stgeq_.htm" title="STRING= (MGL-PAX:CLHS FUNCTION)"><code>string=</code></a>).</p></li>
<li><p>a list: if subscription if for a list structure, and the posted message is also a list structure, then a structure comparison (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_equalp.htm" title="EQUALP (MGL-PAX:CLHS FUNCTION)"><code>equalp</code></a>) is made.</p></li>
</ul></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AUNSUBSCRIBE-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.EVENTSTREAM:UNSUBSCRIBE%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:UNSUBSCRIBE%20GENERIC-FUNCTION" >UNSUBSCRIBE</a></span></span> <span class="locative-args">EVENTSTREAM UNSUBSCRIBER</span></span></p>

<p>Unsubscribe from the eventstream. No more events will be received then.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3APUBLISH-20GENERIC-FUNCTION-29"></a>
<a id="SENTO.EVENTSTREAM:PUBLISH%20GENERIC-FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[generic-function]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:PUBLISH%20GENERIC-FUNCTION" >PUBLISH</a></span></span> <span class="locative-args">EVENTSTREAM MESSAGE</span></span></p>

<p>Publish an event/message to the eventstream. Subscribers may receive notification if they registered for the right message pattern.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3ASUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EEVENTSTREAM-3AEVENTSTREAM-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20SENTO.ACTOR:ACTOR%29%29" >SUBSCRIBE</a></span></span> <span class="locative-args">(EV-STREAM <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>EVENTSTREAM</code></a>) (SUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Subscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3ASUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20SENTO.ACTOR:ACTOR%29%29" >SUBSCRIBE</a></span></span> <span class="locative-args">(SYSTEM <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM</code></a>) (SUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to subscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3ASUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:SUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29" >SUBSCRIBE</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) (SUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to subscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AUNSUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EEVENTSTREAM-3AEVENTSTREAM-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20SENTO.ACTOR:ACTOR%29%29" >UNSUBSCRIBE</a></span></span> <span class="locative-args">(EV-STREAM <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>EVENTSTREAM</code></a>) (UNSUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Unsubscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AUNSUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20SENTO.ACTOR:ACTOR%29%29" >UNSUBSCRIBE</a></span></span> <span class="locative-args">(SYSTEM <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM</code></a>) (UNSUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to unsubscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3AUNSUBSCRIBE-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20SENTO-2EACTOR-3AACTOR-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:UNSUBSCRIBE%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20SENTO.ACTOR:ACTOR%29%29" >UNSUBSCRIBE</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) (UNSUBSCRIBER <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>)</span></span></p>

<p>Convenience. Allows to unsubscribe to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3APUBLISH-20-28METHOD-20NIL-20-28SENTO-2EEVENTSTREAM-3AEVENTSTREAM-20T-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.EVENTSTREAM:EVENTSTREAM%20T%29%29" >PUBLISH</a></span></span> <span class="locative-args">(EV-STREAM <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>EVENTSTREAM</code></a>) MESSAGE</span></span></p>

<p>Publish to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3APUBLISH-20-28METHOD-20NIL-20-28SENTO-2EACTOR-SYSTEM-3AACTOR-SYSTEM-20T-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20T%29%29" >PUBLISH</a></span></span> <span class="locative-args">(SYSTEM <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM</code></a>) MESSAGE</span></span></p>

<p>Convenience. Allows to publish to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EEVENTSTREAM-3APUBLISH-20-28METHOD-20NIL-20-28SENTO-2EACTOR-3AACTOR-20T-29-29-29"></a>
<a id="SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[method]</span> <span class="reference-object"><a href="#SENTO.EVENTSTREAM:PUBLISH%20%28METHOD%20NIL%20%28SENTO.ACTOR:ACTOR%20T%29%29" >PUBLISH</a></span></span> <span class="locative-args">(ACTOR <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>SENTO.ACTOR:ACTOR</code></a>) MESSAGE</span></span></p>

<p>Convenience. Allows to publish to <a href="#SENTO.EVENTSTREAM:EVENTSTREAM%20CLASS" title="SENTO.EVENTSTREAM:EVENTSTREAM CLASS"><code>ev:eventstream</code></a> by just providing the actor.</p></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3A-40FUTURE-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.EVENTSTREAM:@EVENTSTREAM%20MGL-PAX:SECTION" title="Eventstream">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.TASKS:@TASKS%20MGL-PAX:SECTION" title="Tasks">&#8594;</a> <a href="#SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION" title="Future (delayed-computation)">&#8634;</a></span></span></p>
<h3><a href="#SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION">2.10 Future (delayed-computation)</a></h3>
<h6>[in package SENTO.FUTURE with nicknames FUTURE]</h6>
<p><a id="x-28SENTO-2EFUTURE-3AFUTURE-20CLASS-29"></a>
<a id="SENTO.FUTURE:FUTURE%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.FUTURE:FUTURE%20CLASS" >FUTURE</a></span></span></span></p>

<p>The wrapped <a href="https://orthecreedence.github.io/blackbird/" >blackbird</a> <code>promise</code>, here called <code>future</code>.
Not all features of blackbird's <code>promise</code> are supported.
This <code>future</code> wrapper changes the terminology. A <code>future</code> is a delayed computation.
A <code>promise</code> is the fulfillment of the delayed computation.</p></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AWITH-FUT-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FUTURE:WITH-FUT%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FUTURE:WITH-FUT%20MGL-PAX:MACRO" >WITH-FUT</a></span></span> <span class="locative-args">&amp;BODY BODY</span></span></p>

<p>Convenience macro for creating a <a href="#SENTO.FUTURE:FUTURE%20CLASS" title="SENTO.FUTURE:FUTURE CLASS"><code>future</code></a>.</p>

<p>The <code>future</code> will be resolved with the result of the body form.</p></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AWITH-FUT-RESOLVE-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FUTURE:WITH-FUT-RESOLVE%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FUTURE:WITH-FUT-RESOLVE%20MGL-PAX:MACRO" >WITH-FUT-RESOLVE</a></span></span> <span class="locative-args">&amp;BODY BODY</span></span></p>

<p>Convenience macro for creating a <a href="#SENTO.FUTURE:FUTURE%20CLASS" title="SENTO.FUTURE:FUTURE CLASS"><code>future</code></a> that must be resolved manually via <code>fresolve</code>.</p>

<p>This allows to spawn threads or other asynchronous operations as part of <code>body</code>.
However, you have to <code>resolve</code> the future eventually by applying a result on <code>resolve</code>.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">with-fut-resolve</span></i>
  <span class="paren2">(<span class="code">bt2:make-thread
   <span class="paren3">(<span class="code"><i><span class="symbol">lambda</span></i> <span class="paren4">(<span class="code"></span>)</span>
     <span class="paren4">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren5">(<span class="code"><span class="paren6">(<span class="code">result <span class="paren1">(<span class="code">do-some-lengthy-calculation</span>)</span></span>)</span></span>)</span>
       <span class="paren5">(<span class="code">fresolve result</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AMAKE-FUTURE-20FUNCTION-29"></a>
<a id="SENTO.FUTURE:MAKE-FUTURE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.FUTURE:MAKE-FUTURE%20FUNCTION" >MAKE-FUTURE</a></span></span> <span class="locative-args">EXECUTE-FUN</span></span></p>

<p>Creates a future. <code>execute-fun</code> is the lambda that is executed when the future is created.
<code>execute-fun</code> takes a parameter which is the <code>execute-fun</code> funtion. <code>execute-fun</code> function
takes the <code>promise</code> as parameter which is the computed value. Calling <code>execute-fun</code> with the promise
will fulfill the <a href="#SENTO.FUTURE:FUTURE%20CLASS" title="SENTO.FUTURE:FUTURE CLASS"><code>future</code></a>.
Manually calling <code>execute-fun</code> to fulfill the <code>future</code> is in contrast to just fulfill the <code>future</code> from a return value. The benefit of the <code>execute-fun</code> is flexibility. In  a multi-threaded environment <code>execute-fun</code> could spawn a thread, in which case <code>execute-fun</code> would return immediately but no promise-value can be given at that time. The <code>execute-fun</code> can be called from a thread and provide the promise.</p>

<p>Create a future with:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">make-future <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="code">execute-fun</span>)</span>
               <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">promise <span class="paren6">(<span class="code">delayed-computation</span>)</span></span>)</span></span>)</span>
                 <span class="paren4">(<span class="code">bt2:make-thread <span class="paren5">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren6">(<span class="code"></span>)</span>
                   <span class="paren6">(<span class="code">sleep 0.5</span>)</span>
                   <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_232.html#IDX618" class="symbol">funcall</a> execute-fun promise</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3ACOMPLETE-P-20FUNCTION-29"></a>
<a id="SENTO.FUTURE:COMPLETE-P%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.FUTURE:COMPLETE-P%20FUNCTION" >COMPLETE-P</a></span></span> <span class="locative-args">FUTURE</span></span></p>

<p>Is <code>future</code> completed? Returns either <code>t</code> or <code>nil</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AFCOMPLETED-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FUTURE:FCOMPLETED%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FUTURE:FCOMPLETED%20MGL-PAX:MACRO" >FCOMPLETED</a></span></span> <span class="locative-args">FUTURE (RESULT) &amp;BODY BODY</span></span></p>

<p>Completion handler on the given <code>future</code>.</p>

<p>If the <code>future</code> is already complete then the <code>body</code> executes immediately.
<code>result</code> represents the future result.
<code>body</code> is executed when future completed.
Returns the future.</p>

<p>Notes on execution context:
By calling <code>fcompleted</code> a completion function is installed on the <code>future</code>.
If the <code>future</code>s execute function is not delaying or called by the same thread as the one calling <code>fcompleted</code>,
then <code>body</code> is called by the callers thread.
If, however, the <code>future</code> is delaying and doing computation in another thread and later also resolving the <code>future</code> in that thread (this depends on how the <code>future</code> is defined), then the <code>body</code> form is executed by the thread that is resolving the <code>future</code>.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">fcompleted <span class="paren2">(<span class="code"><i><span class="symbol">with-fut</span></i>
              <span class="paren3">(<span class="code">sleep .5</span>)</span>
              1</span>)</span>
            <span class="paren2">(<span class="code">result</span>)</span>
  <span class="paren2">(<span class="code">format t <span class="string">"Future result ~a~%"</span> result</span>)</span></span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AFRESULT-20FUNCTION-29"></a>
<a id="SENTO.FUTURE:FRESULT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.FUTURE:FRESULT%20FUNCTION" >FRESULT</a></span></span> <span class="locative-args">FUTURE</span></span></p>

<p>Get the computation result. If not yet available <code>:not-ready</code> is returned.</p></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AFMAP-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FUTURE:FMAP%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FUTURE:FMAP%20MGL-PAX:MACRO" >FMAP</a></span></span> <span class="locative-args">FUTURE (RESULT) &amp;BODY BODY</span></span></p>

<p><code>fmap</code> maps a future.</p>

<p><code>future</code> is the future that is mapped.
<code>result</code> is the result of the future when it completed.
<code>body</code> is the form that executes when the future is completed. The result of <code>body</code> generates a new future.</p>

<p>Notes on execution context:
By calling <code>fmap</code> a mapping function is installed on the <code>future</code>.
If the <code>future</code>s execute function is not delaying or called by the same thread as the one calling <code>fmap</code>,
then <code>body</code> is called by the callers thread.
If, however, the <code>future</code> is delaying and doing computation in another thread and later also resolving the <code>future</code> in that thread (this depends on how the <code>future</code> is defined), then the <code>body</code> form is executed by the thread that is resolving the <code>future</code>.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">fmap <span class="paren2">(<span class="code"><i><span class="symbol">with-fut</span></i> 0</span>)</span> <span class="paren2">(<span class="code">result</span>)</span>
  <span class="paren2">(<span class="code">1+ result</span>)</span></span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2EFUTURE-3AFRECOVER-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.FUTURE:FRECOVER%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.FUTURE:FRECOVER%20MGL-PAX:MACRO" >FRECOVER</a></span></span> <span class="locative-args">FUTURE &amp;REST HANDLER-FORMS</span></span></p>

<p>Catch errors in futures using <code>frecover</code>
It works similar to <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm" title="HANDLER-CASE (MGL-PAX:CLHS MGL-PAX:MACRO)"><code>handler-case</code></a>.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code">fresult
 <span class="paren2">(<span class="code">frecover
  <span class="paren3">(<span class="code">-&gt; <span class="paren4">(<span class="code"><i><span class="symbol">with-fut</span></i> 0</span>)</span>
    <span class="paren4">(<span class="code">fmap <span class="paren5">(<span class="code">value</span>)</span>
      <span class="paren5">(<span class="code">declare <span class="paren6">(<span class="code">ignore value</span>)</span></span>)</span>
      <span class="paren5">(<span class="code">error <span class="string">"foo"</span></span>)</span></span>)</span></span>)</span>
    <span class="paren3">(<span class="code">fmap <span class="paren4">(<span class="code">value</span>)</span>
      <span class="paren4">(<span class="code">+ value 1</span>)</span></span>)</span></span>)</span></span>)</span>
  <span class="paren1">(<span class="code">error <span class="paren2">(<span class="code">c</span>)</span> <span class="paren2">(<span class="code">format nil <span class="string">"~a"</span> c</span>)</span></span>)</span>))</span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3A-40TASKS-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.TASKS:@TASKS%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.FUTURE:@FUTURE%20MGL-PAX:SECTION" title="Future (delayed-computation)">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION" title="Config">&#8594;</a> <a href="#SENTO.TASKS:@TASKS%20MGL-PAX:SECTION" title="Tasks">&#8634;</a></span></span></p>
<h3><a href="#SENTO.TASKS:@TASKS%20MGL-PAX:SECTION">2.11 Tasks</a></h3>
<h6>[in package SENTO.TASKS with nicknames TASKS]</h6>
<p><a id="x-28SENTO-2ETASKS-3AWITH-CONTEXT-20MGL-PAX-3AMACRO-29"></a>
<a id="SENTO.TASKS:WITH-CONTEXT%20MGL-PAX:MACRO"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[macro]</span> <span class="reference-object"><a href="#SENTO.TASKS:WITH-CONTEXT%20MGL-PAX:MACRO" >WITH-CONTEXT</a></span></span> <span class="locative-args">(CONTEXT &amp;OPTIONAL (DISPATCHER <code>:SHARED</code>)) &amp;BODY BODY</span></span></p>

<p><code>with-context</code> creates an environment where the <code>tasks</code> package functions should be used in.
<code>context</code> can be either an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>, an <a href="#SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT%20CLASS" title="SENTO.ACTOR-CONTEXT:ACTOR-CONTEXT CLASS"><code>ac:actor-context</code></a>, or an <a href="#SENTO.ACTOR:ACTOR%20CLASS" title="SENTO.ACTOR:ACTOR CLASS"><code>act:actor</code></a> (or subclass).
<code>dispatcher</code> specifies the dispatcher where the tasks is executed in (like thread-pool).
The tasks created using the <code>tasks</code> functions will then be created in the given context.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="comment">;; create actor-system
</span><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  <span class="paren2">(<span class="code">task-yield <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span> <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a> 1 1</span>)</span></span>)</span></span>)</span></span>)</span>

=&gt; 2 <span class="paren1">(<span class="code">2 bits, #x2, #o2, #b10</span>)</span>
</span></code></pre>

<p>Since the default <code>:shared</code> dispatcher should mainly be used for the message dispatching, 
but not so much for longer running tasks it is possible to create an actor system with additional
dispatchers. This additional dispatcher can be utilized for <code>tasks</code>. Be aware that the config as used below is merged with the <a href="#SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG*%20VARIABLE" title="SENTO.ACTOR-SYSTEM:*DEFAULT-CONFIG* VARIABLE"><code>asys:*default-config*</code></a> which means that the dispatcher <code>:foo</code> here is really an additional dispatcher.</p>

<pre><code><span class="code"><span class="comment">;; create actor-system with additional (custom) dispatcher
</span><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">asys:make-actor-system '<span class="paren3">(<span class="code"><span class="keyword">:dispatchers</span> <span class="paren4">(<span class="code"><span class="keyword">:foo</span> <span class="paren5">(<span class="code"><span class="keyword">:workers</span> 16</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span> <span class="keyword">:foo</span></span>)</span>
  <span class="paren2">(<span class="code">task-yield <span class="paren3">(<span class="code"><i><span class="symbol">lambda</span></i> <span class="paren4">(<span class="code"></span>)</span> <span class="paren4">(<span class="code">+ 1 1</span>)</span></span>)</span></span>)</span></span>)</span>
</span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3A-2ATASK-CONTEXT-2A-20VARIABLE-29"></a>
<a id="SENTO.TASKS:*TASK-CONTEXT*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.TASKS:*TASK-CONTEXT*%20VARIABLE" >*TASK-CONTEXT*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Optionally set this globally to use the API without using <a href="#SENTO.TASKS:WITH-CONTEXT%20MGL-PAX:MACRO" title="SENTO.TASKS:WITH-CONTEXT MGL-PAX:MACRO"><code>with-context</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3A-2ATASK-DISPATCHER-2A-20VARIABLE-29"></a>
<a id="SENTO.TASKS:*TASK-DISPATCHER*%20VARIABLE"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[variable]</span> <span class="reference-object"><a href="#SENTO.TASKS:*TASK-DISPATCHER*%20VARIABLE" >*TASK-DISPATCHER*</a></span></span> <span class="locative-args">NIL</span></span></p>

<p>Optionally set a dispatcher id. Same applies here as for <a href="#SENTO.TASKS:*TASK-CONTEXT*%20VARIABLE" title="SENTO.TASKS:*TASK-CONTEXT* VARIABLE"><code>*task-context*</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-YIELD-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-YIELD%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-YIELD%20FUNCTION" >TASK-YIELD</a></span></span> <span class="locative-args">FUN &amp;OPTIONAL TIME-OUT</span></span></p>

<p><code>task-yield</code> runs the given function <code>fun</code> by blocking and waiting for a response from the <code>task</code>, or until the given timeout was elapsed.
<code>fun</code> must be a 0-arity function.</p>

<p>A normal response from the actor is passed back as the response value.
If the timeout elapsed the response is: <code>(values :handler-error miscutils:ask-timeout)</code>.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="comment">;; create actor-system
</span><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  <span class="paren2">(<span class="code">task-yield <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span> <span class="paren4">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a> 1 1</span>)</span></span>)</span></span>)</span></span>)</span>

=&gt; 2 <span class="paren1">(<span class="code">2 bits, #x2, #o2, #b10</span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-START-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-START%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-START%20FUNCTION" >TASK-START</a></span></span> <span class="locative-args">FUN</span></span></p>

<p><code>task-start</code> runs the given function <code>fun</code> asynchronously.
<code>fun</code> must be a 0-arity function.
Use this if you don't care about any response or result, i.e. for I/O side-effects.
It returns <code>(values :ok &lt;task&gt;)</code>. `<task> is in fact an actor given back as reference.
The task is automatically stopped and removed from the context and will not be able to handle requests.</p></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-ASYNC-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-ASYNC%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-ASYNC%20FUNCTION" >TASK-ASYNC</a></span></span> <span class="locative-args">FUN &amp;KEY ON-COMPLETE-FUN</span></span></p>

<p><code>task-async</code> schedules the function <code>fun</code> for asynchronous execution.
<code>fun</code> must be a 0-arity function.
<code>on-complete-fun</code> is a 1-arity completion handler function. When called the result is delivered.
The completion handler function parameter may also be a <code>(cons :handler-error condition)</code> construct in case an error happened within the message handling.</p>

<p>Be aware about the execution of the completion function:
The completion function is, by a very high chance, executed by the thread that executed <code>fun</code> function.
Only in very rare cases it could be possible that the completion function is executed by the caller of <code>task-async</code>. See <a href="#SENTO.FUTURE:FCOMPLETED%20MGL-PAX:MACRO" title="SENTO.FUTURE:FCOMPLETED MGL-PAX:MACRO"><code>future:fcompleted</code></a> for more info.</p>

<p>Using <code>task-async</code> provides two alternatives:</p>

<ul>
<li><p>together with <a href="#SENTO.TASKS:TASK-AWAIT%20FUNCTION" title="SENTO.TASKS:TASK-AWAIT FUNCTION"><code>task-await</code></a></p></li>
<li><p>or with completion handler</p></li>
</ul>

<p>In fact it is possible to call <code>task-await</code> as well, but then you probably don't need a completion handler.
Using the completion handler makes the processing complete asynchronous.</p>

<p>The result of <code>task-async</code> is a <code>task</code>.
Store this <code>task</code> for a call to <code>task-async</code> (even with or without using <code>on-complete-fun</code>).
When <em>not</em> using <code>on-complete-fun</code> users must call either <code>task-await</code> or <a href="#SENTO.TASKS:TASK-SHUTDOWN%20FUNCTION" title="SENTO.TASKS:TASK-SHUTDOWN FUNCTION"><code>task-shutdown</code></a> for the task to be cleaned up.
When using <code>on-complete-fun</code> this is done for you.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="comment">;; create actor-system
</span><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  <span class="paren2">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_141.html#IDX422" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">x <span class="paren5">(<span class="code">task-async <span class="paren6">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren1">(<span class="code"></span>)</span> <span class="paren1">(<span class="code">some bigger computation</span>)</span></span>)</span></span>)</span></span>)</span>
        <span class="paren4">(<span class="code">y 1</span>)</span></span>)</span>
    <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a> <span class="paren4">(<span class="code">task-await x</span>)</span> y</span>)</span></span>)</span></span>)</span>

<span class="comment">;; use-case with `on-complete-fun`
</span><span class="paren1">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_167.html#IDX483" class="symbol"><i><span class="symbol">defun</span></i></a> my-task-completion <span class="paren2">(<span class="code">result</span>)</span>
  <span class="paren2">(<span class="code">do-something-with result</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  <span class="paren2">(<span class="code">task-async <span class="paren3">(<span class="code"><a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_330.html#IDX1006" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="code"></span>)</span> <span class="paren4">(<span class="code">some-bigger-computation</span>)</span></span>)</span>
              <span class="keyword">:on-complete-fun</span> #'my-task-completion</span>)</span></span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-AWAIT-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-AWAIT%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-AWAIT%20FUNCTION" >TASK-AWAIT</a></span></span> <span class="locative-args">TASK &amp;OPTIONAL TIME-OUT</span></span></p>

<p><code>task-await</code> waits (by blocking) until a result has been generated for a previous <a href="#SENTO.TASKS:TASK-ASYNC%20FUNCTION" title="SENTO.TASKS:TASK-ASYNC FUNCTION"><code>task-async</code></a> by passing the <code>task</code> result of <code>task-async</code> to <code>task-await</code>.
Specify <code>time-out</code> in seconds. If <code>task-await</code> times out a <code>(cons :handler-error 'ask-timeout)</code> will be returned.
<code>task-await</code> also stops the <code>task</code> that is the result of <code>task-async</code>, so it is of no further use.</p></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-SHUTDOWN-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-SHUTDOWN%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-SHUTDOWN%20FUNCTION" >TASK-SHUTDOWN</a></span></span> <span class="locative-args">TASK</span></span></p>

<p><code>task-shutdown</code> shuts down a task in order to clean up resources.</p></li>
</ul>
<p><a id="x-28SENTO-2ETASKS-3ATASK-ASYNC-STREAM-20FUNCTION-29"></a>
<a id="SENTO.TASKS:TASK-ASYNC-STREAM%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.TASKS:TASK-ASYNC-STREAM%20FUNCTION" >TASK-ASYNC-STREAM</a></span></span> <span class="locative-args">FUN LST</span></span></p>

<p><code>task-async-stream</code> concurrently applies <code>fun</code> on all elements of <code>lst</code>.
<code>fun</code> must be a one-arity function taking an element of <code>lst</code>.</p>

<p>The concurrency depends on the number of available <code>:shared</code> dispatcher workers.
Each element of <code>lst</code> is processed by a worker of the <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a>s <code>:shared</code> dispatcher.
If all workers are busy then the computation of <code>fun</code> is queued.</p>

<p>Example:</p>

<pre><code><span class="code"><span class="comment">;; create actor-system
</span><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*sys*</span> <span class="paren2">(<span class="code">make-actor-system</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><i><span class="symbol">with-context</span></i> <span class="paren2">(<span class="code"><span class="special">*sys*</span></span>)</span>
  <span class="paren2">(<span class="code">-&gt;&gt; 
    '<span class="paren3">(<span class="code">1 2 3 4 5</span>)</span>
    <span class="paren3">(<span class="code">task-async-stream #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX103" class="symbol">1+</a></span>)</span>
    <span class="paren3">(<span class="code">reduce #'<a href="http://www.gnu.org/software/emacs/elisp-manual/html_node/elisp_63.html#IDX105" class="symbol">+</a></span>)</span></span>)</span></span>)</span>

=&gt; 20 <span class="paren1">(<span class="code">5 bits, #x14, #o24, #b10100</span>)</span></span></code></pre></li>
</ul>
<p><a id="x-28SENTO-2ECONFIG-3A-40CONFIG-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.TASKS:@TASKS%20MGL-PAX:SECTION" title="Tasks">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.WHEEL-TIMER:@SCHEDULER%20MGL-PAX:SECTION" title="Scheduler">&#8594;</a> <a href="#SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION" title="Config">&#8634;</a></span></span></p>
<h3><a href="#SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION">2.12 Config</a></h3>
<h6>[in package SENTO.CONFIG with nicknames CONFIG]</h6>
<p><a id="x-28SENTO-2ECONFIG-3ACONFIG-FROM-20FUNCTION-29"></a>
<a id="SENTO.CONFIG:CONFIG-FROM%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.CONFIG:CONFIG-FROM%20FUNCTION" >CONFIG-FROM</a></span></span> <span class="locative-args">CONFIG-STRING</span></span></p>

<p>Parses the given config-string, represented by common lisp s-expressions.
The config is composed of plists in a hierarchy.</p>

<p>This function parses (run through <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_rd.htm" title="READ (MGL-PAX:CLHS FUNCTION)"><code>cl:read</code></a>) the given config string.
The config string can be generated by:</p>

<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code"><span class="special">*print-case*</span> <span class="keyword">:downcase</span></span>)</span></span>)</span>
  <span class="paren2">(<span class="code">prin1-to-string '<span class="paren3">(<span class="code"><i><span class="symbol">defconfig</span></i> 
                     <span class="paren4">(<span class="code"><span class="keyword">:foo</span> 1
                      <span class="keyword">:bar</span> 2</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>

<p>Or just be given by reading from a file.
Notice the 'config' s-expr must start with the root <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_car_c.htm" title="CAR (MGL-PAX:CLHS FUNCTION)"><code>car</code></a> 'defconfig'.</p></li>
</ul>
<p><a id="x-28SENTO-2ECONFIG-3ARETRIEVE-SECTION-20FUNCTION-29"></a>
<a id="SENTO.CONFIG:RETRIEVE-SECTION%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.CONFIG:RETRIEVE-SECTION%20FUNCTION" >RETRIEVE-SECTION</a></span></span> <span class="locative-args">CONFIG SECTION</span></span></p>

<p>Retrieves the given named section which should be a (global) <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm" title="SYMBOL (MGL-PAX:CLHS CLASS)"><code>symbol</code></a> (a key).
A section usually is a plist with additional configs or sub sections.
This function looks only in the root hierarchy of the given config.</p></li>
</ul>
<p><a id="x-28SENTO-2ECONFIG-3ARETRIEVE-VALUE-20FUNCTION-29"></a>
<a id="SENTO.CONFIG:RETRIEVE-VALUE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.CONFIG:RETRIEVE-VALUE%20FUNCTION" >RETRIEVE-VALUE</a></span></span> <span class="locative-args">SECTION KEY</span></span></p>

<p>Retrieves the value for the given key and section.</p></li>
</ul>
<p><a id="x-28SENTO-2ECONFIG-3ARETRIEVE-KEYS-20FUNCTION-29"></a>
<a id="SENTO.CONFIG:RETRIEVE-KEYS%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.CONFIG:RETRIEVE-KEYS%20FUNCTION" >RETRIEVE-KEYS</a></span></span> <span class="locative-args">CONFIG</span></span></p>

<p>Retrieves all section keys</p></li>
</ul>
<p><a id="x-28SENTO-2ECONFIG-3AMERGE-CONFIG-20FUNCTION-29"></a>
<a id="SENTO.CONFIG:MERGE-CONFIG%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.CONFIG:MERGE-CONFIG%20FUNCTION" >MERGE-CONFIG</a></span></span> <span class="locative-args">CONFIG FALLBACK-CONFIG</span></span></p>

<p>Merges config. 
<code>config</code> specifies a config that overrides what exists in <code>fallback-config</code>.
<code>fallback-config</code> is a default. If something doesn't exist in <code>config</code> it is taken from <code>fallback-config</code>.
Both <code>config</code> and <code>fallback-config</code> must be plists, or a 'config' that was the output of <a href="#SENTO.CONFIG:CONFIG-FROM%20FUNCTION" title="SENTO.CONFIG:CONFIG-FROM FUNCTION"><code>config-from</code></a>.</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3A-40SCHEDULER-20MGL-PAX-3ASECTION-29"></a>
<a id="SENTO.WHEEL-TIMER:@SCHEDULER%20MGL-PAX:SECTION"></a></p>
<p><span class="outer-navigation"><span class="navigation"> <a href="#SENTO.CONFIG:@CONFIG%20MGL-PAX:SECTION" title="Config">&#8592;</a> <a href="#SENTO.DOCS:@API%20MGL-PAX:SECTION" title="API documentation">&#8593;</a> <a href="#SENTO.WHEEL-TIMER:@SCHEDULER%20MGL-PAX:SECTION" title="Scheduler">&#8634;</a></span></span></p>
<h3><a href="#SENTO.WHEEL-TIMER:@SCHEDULER%20MGL-PAX:SECTION">2.13 Scheduler</a></h3>
<h6>[in package SENTO.WHEEL-TIMER with nicknames WT]</h6>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3AWHEEL-TIMER-20CLASS-29"></a>
<a id="SENTO.WHEEL-TIMER:WHEEL-TIMER%20CLASS"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[class]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:WHEEL-TIMER%20CLASS" >WHEEL-TIMER</a></span></span></span></p>

<p>Wheel timer class</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3AMAKE-WHEEL-TIMER-20FUNCTION-29"></a>
<a id="SENTO.WHEEL-TIMER:MAKE-WHEEL-TIMER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:MAKE-WHEEL-TIMER%20FUNCTION" >MAKE-WHEEL-TIMER</a></span></span> <span class="locative-args">&amp;REST CONFIG</span></span></p>

<p>Creates a new <a href="#SENTO.WHEEL-TIMER:WHEEL-TIMER%20CLASS" title="SENTO.WHEEL-TIMER:WHEEL-TIMER CLASS"><code>wt:wheel-timer</code></a>.</p>

<p><code>config</code> is a parameter for a list of key parameters including:</p>

<ul>
<li><p><code>:resolution</code> the timer time resolution in milliseconds. 100 milliseconds is a good default.</p></li>
<li><p><code>:max-size</code> the number of timer slots this wheel should have.</p></li>
</ul>

<p>Note that an <a href="#SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%20CLASS" title="SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM CLASS"><code>asys:actor-system</code></a> includes an instance as <a href="#SENTO.ACTOR-SYSTEM:SCHEDULER%20%28MGL-PAX:READER%20SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM%29" title="SENTO.ACTOR-SYSTEM:SCHEDULER (MGL-PAX:READER SENTO.ACTOR-SYSTEM:ACTOR-SYSTEM)"><code>asys:scheduler</code></a> that can be used within actors.
But you can also create your own instance.</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3ASHUTDOWN-WHEEL-TIMER-20FUNCTION-29"></a>
<a id="SENTO.WHEEL-TIMER:SHUTDOWN-WHEEL-TIMER%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:SHUTDOWN-WHEEL-TIMER%20FUNCTION" >SHUTDOWN-WHEEL-TIMER</a></span></span> <span class="locative-args">WHEEL-TIMER</span></span></p>

<p>Shuts down the wheel timer and free resources.</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3ASCHEDULE-ONCE-20FUNCTION-29"></a>
<a id="SENTO.WHEEL-TIMER:SCHEDULE-ONCE%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:SCHEDULE-ONCE%20FUNCTION" >SCHEDULE-ONCE</a></span></span> <span class="locative-args">WHEEL-TIMER DELAY TIMER-FUN &amp;KEY (SIG <code>NIL</code>) (REUSE-SIG <code>NIL</code>)</span></span></p>

<p>Schedule a function execution once:</p>

<ul>
<li><p><code>wheel-timer</code> is the <code>wt:wheel-timer</code> instance.</p></li>
<li><p><code>delay</code> is the number of seconds (float) delay when <code>timer-fun</code> should be executed.</p></li>
<li><p><code>timer-fun</code> is a 0-arity function that is executed after <code>delay</code>. BEWARE: the function is executed in the timer thread. Make sure that you off-load long running tasks to other threads, or to a custom dispatcher (i.e. <code>tasks</code>).</p></li>
<li><p><code>sig</code> is an optional symbol or string that is used to identify the timer and is used for <a href="#SENTO.WHEEL-TIMER:CANCEL%20FUNCTION" title="SENTO.WHEEL-TIMER:CANCEL FUNCTION"><code>cancel</code></a>.</p></li>
<li><p><code>reuse-sig</code> is a boolean that indicates whether the signature should be cleaned up after the timer has been executed.</p></li>
</ul>

<p>Returns: signature (symbol) that represents the timer and can be used to cancel the timer.</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3ASCHEDULE-RECURRING-20FUNCTION-29"></a>
<a id="SENTO.WHEEL-TIMER:SCHEDULE-RECURRING%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:SCHEDULE-RECURRING%20FUNCTION" >SCHEDULE-RECURRING</a></span></span> <span class="locative-args">WHEEL-TIMER INITIAL-DELAY DELAY TIMER-FUN &amp;OPTIONAL (SIG <code>NIL</code>)</span></span></p>

<p>Schedule a recurring function execution:</p>

<ul>
<li><p><code>wheel-timer</code> is the <code>wt:wheel-timer</code> instance.</p></li>
<li><p><code>initial-delay</code> is the number of seconds (float) delay when <code>timer-fun</code> is executed the first time.</p></li>
<li><p><code>delay</code> is the number of seconds (float) delay when <code>timer-fun</code> should be executed.</p></li>
<li><p><code>timer-fun</code> is a 0-arity function that is executed after <code>delay</code>. BEWARE: the function is executed in the timer thread. Make sure that you off-load long running tasks to other threads, or to a custom dispatcher (i.e. <code>tasks</code>).</p></li>
<li><p><code>sig</code> is an optional symbol or string that is used to identify the timer and is used for <code>cancel-recurring</code>.</p></li>
</ul>

<p>Returns the signature that was either passed in via <code>sig</code> or a generated one.
The signature can be used to cancel the timer via <code>cancel-recurring</code>.</p></li>
</ul>
<p><a id="x-28SENTO-2EWHEEL-TIMER-3ACANCEL-20FUNCTION-29"></a>
<a id="SENTO.WHEEL-TIMER:CANCEL%20FUNCTION"></a></p>
<ul>
<li><p><span class=reference-bullet><span class=reference><span class="locative-type">[function]</span> <span class="reference-object"><a href="#SENTO.WHEEL-TIMER:CANCEL%20FUNCTION" >CANCEL</a></span></span> <span class="locative-args">WHEEL-TIMER SIG</span></span></p>

<p>Cancels a timer with the given signature <code>sig</code>.</p></li>
</ul>
  </div>
</div>
<script>$('#page-toc').toc({'selectors': 'h1,h2,h3,h4'});</script>
</body>
</html>
